packages feed

github 0.13.2 → 0.30.0.2

raw patch · 233 files changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,422 @@+## 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/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/haskell-github/github/pull/306)+- Add "Get archive link" API+  [#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/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/haskell-github/github/pull/308)+- Add list organisation invitations endpoint++## Changes for 0.18++_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/haskell-github/github/pull/296)+- Add `archived` field to `Repo`.+  [#298](https://github.com/haskell-github/github/pull/298)+- Update dependencies.+  [#295](https://github.com/haskell-github/github/pull/295)+- Add Statuses endpoints.+  [#268](https://github.com/haskell-github/github/pull/268)+- Add requested reviewers field to pull request records.+  [#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+- Pull Request review endpoints++## 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`++## Changes for 0.15.0++_2016-11-04, Oleg Grenrus_++- Reworked `PullRequest` (notably `pullRequestsFor`)+- Reworked PR and Issue filtering+- GHC-8.0.1 support+- Change `repoMasterBranch` to `repoDefaultBranch` in `Repo`+- Add `listTeamReposR`+- Add `myStarredAcceptStarR`+- Add `HeaderQuery` to `Request`+- Add `Hashable Auth` instance+- Add `mkUserId`, `mkUserName`, `fromUserId`, `fromOrganizationId`+- Add `userIssuesR`+- Add `organizationIssuesR`+- Make `teamName :: Text` amnd `teamSlug :: Name Team` in both: `Team` and `SimpleTeam`+- 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.++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`,+  `RepoPublicity`+- Don't require network access for search tests++## Changes for 0.14.0++_2016-01-25, Oleg Grenrus_++Large API changes:++- Use `Text` and `Vector` in place of `String` and `[]`.+- Use `Name` and `Id` tagged types for names and identifiers.+- Make detailed structures un-prefixed, simple ones prefixed with `Simple`. Example: `Team` and `SimpleTeam`.+- Decouple request creation from execution (`*R` and `executeRequest*` functions).+- 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:++_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.+* The above by [John Wiegley](https://github.com/jwiegley).++## Changes for 0.4.1:++_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:++_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`.+* Private gists, issues, organizations, pull requests, and users.+* Lock down `tls` and `tls-extra` instead of keeping up with the+  ever-changing `http-conduit` package.+* Features by [Pavel Ryzhov](https://github.com/paulrzcz) and [Simon Hengel](https://github.com/sol).++## Changes for 0.2.1:++_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.+* 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.+* Bugs found and squashed thanks to [Joey Hess](https://github.com/joeyh) and [Simon Hengel](https://github.com/sol).
− Github/Auth.hs
@@ -1,4 +0,0 @@--- | The Github auth data type-module Github.Auth (P.GithubAuth(..)) where--import qualified Github.Private as P
− Github/Data.hs
@@ -1,721 +0,0 @@-{-# LANGUAGE CPP, DeriveDataTypeable, OverloadedStrings #-}---- | This module re-exports the @Github.Data.Definitions@ module, adding--- instances of @FromJSON@ to it. If you wish to use the data without the--- instances, use the @Github.Data.Definitions@ module instead.--module Github.Data (module Github.Data.Definitions) where--import Control.Applicative-import Control.Monad-import qualified Data.Text as T-import Data.Aeson.Types-import qualified Data.Vector as V-import qualified Data.HashMap.Lazy as Map-import Data.Hashable (Hashable)--#if MIN_VERSION_base(4,8,0)-import Data.Time-#else-import Data.Time-import System.Locale (defaultTimeLocale)-#endif--import Github.Data.Definitions--instance FromJSON GithubDate where-  parseJSON (String t) =-    case parseTime defaultTimeLocale "%FT%T%Z" (T.unpack t) of-         Just d -> pure $ GithubDate d-         _      -> fail "could not parse Github datetime"-  parseJSON _          = fail "Given something besides a String"--instance FromJSON Commit where-  parseJSON (Object o) =-    Commit <$> o .: "sha"-           <*> o .: "parents"-           <*> o .: "url"-           <*> o .: "commit"-           <*> o .:? "committer"-           <*> o .:? "author"-           <*> o .:< "files"-           <*> o .:? "stats"-  parseJSON _          = fail "Could not build a Commit"--instance FromJSON Tree where-  parseJSON (Object o) =-    Tree <$> o .: "sha"-         <*> o .: "url"-         <*> o .:< "tree"-  parseJSON _          = fail "Could not build a Tree"--instance FromJSON GitTree where-  parseJSON (Object o) =-    GitTree <$> o .: "type"-         <*> o .: "sha"-         <*> o .:? "url"-         <*> o .:? "size"-         <*> o .: "path"-         <*> o .: "mode"-  parseJSON _          = fail "Could not build a GitTree"--instance FromJSON GitCommit where-  parseJSON (Object o) =-    GitCommit <$> o .: "message"-              <*> o .: "url"-              <*> o .: "committer"-              <*> o .: "author"-              <*> o .: "tree"-              <*> o .:? "sha"-              <*> o .:< "parents"-  parseJSON _          = fail "Could not build a GitCommit"--instance FromJSON GithubOwner where-  parseJSON (Object o)-    | o `at` "gravatar_id" == Nothing =-      GithubOrganization <$> o .: "avatar_url"-                 <*> o .: "login"-                 <*> o .: "url"-                 <*> o .: "id"-    | otherwise =-      GithubUser <$> o .: "avatar_url"-                 <*> o .: "login"-                 <*> o .: "url"-                 <*> o .: "id"-                 <*> o .: "gravatar_id"-  parseJSON v          = fail $ "Could not build a GithubOwner out of " ++ (show v)--instance FromJSON GitUser where-  parseJSON (Object o) =-    GitUser <$> o .: "name"-            <*> o .: "email"-            <*> o .: "date"-  parseJSON _          = fail "Could not build a GitUser"--instance FromJSON File where-  parseJSON (Object o) =-    File <$> o .: "blob_url"-         <*> o .: "status"-         <*> o .: "raw_url"-         <*> o .: "additions"-         <*> o .: "sha"-         <*> o .: "changes"-         <*> o .: "patch"-         <*> o .: "filename"-         <*> o .: "deletions"-  parseJSON _          = fail "Could not build a File"--instance FromJSON Stats where-  parseJSON (Object o) =-    Stats <$> o .: "additions"-          <*> o .: "total"-          <*> o .: "deletions"-  parseJSON _          = fail "Could not build a Stats"--instance FromJSON Comment where-  parseJSON (Object o) =-    Comment <$> o .:? "position"-            <*> o .:? "line"-            <*> o .: "body"-            <*> o .:? "commit_id"-            <*> o .: "updated_at"-            <*> o .:? "html_url"-            <*> o .: "url"-            <*> o .: "created_at"-            <*> o .:? "path"-            <*> o .: "user"-            <*> o .: "id"-  parseJSON _          = fail "Could not build a Comment"--instance ToJSON NewComment where-  toJSON (NewComment b) = object [ "body" .= b ]--instance ToJSON EditComment where-  toJSON (EditComment b) = object [ "body" .= b ]--instance FromJSON Diff where-  parseJSON (Object o) =-    Diff <$> o .: "status"-         <*> o .: "behind_by"-         <*> o .: "patch_url"-         <*> o .: "url"-         <*> o .: "base_commit"-         <*> o .:< "commits"-         <*> o .: "total_commits"-         <*> o .: "html_url"-         <*> o .:< "files"-         <*> o .: "ahead_by"-         <*> o .: "diff_url"-         <*> o .: "permalink_url"-  parseJSON _          = fail "Could not build a Diff"--instance FromJSON Gist where-  parseJSON (Object o) =-    Gist <$> o .: "user"-         <*> o .: "git_push_url"-         <*> o .: "url"-         <*> o .:? "description"-         <*> o .: "created_at"-         <*> o .: "public"-         <*> o .: "comments"-         <*> o .: "updated_at"-         <*> o .: "html_url"-         <*> o .: "id"-         <*> o `values` "files"-         <*> o .: "git_push_url"-  parseJSON _          = fail "Could not build a Gist"--instance FromJSON GistFile where-  parseJSON (Object o) =-    GistFile <$> o .: "type"-             <*> o .: "raw_url"-             <*> o .: "size"-             <*> o .:? "language"-             <*> o .: "filename"-             <*> o .:? "content"-  parseJSON _          = fail "Could not build a GistFile"--instance FromJSON GistComment where-  parseJSON (Object o) =-    GistComment <$> o .: "user"-                <*> o .: "url"-                <*> o .: "created_at"-                <*> o .: "body"-                <*> o .: "updated_at"-                <*> o .: "id"-  parseJSON _          = fail "Could not build a GistComment"--instance FromJSON Blob where-  parseJSON (Object o) =-    Blob <$> o .: "url"-         <*> o .: "encoding"-         <*> o .: "content"-         <*> o .: "sha"-         <*> o .: "size"-  parseJSON _          = fail "Could not build a Blob"--instance ToJSON NewGitReference where-  toJSON (NewGitReference r s) = object [ "ref" .= r, "sha" .= s  ]--instance FromJSON GitReference where-  parseJSON (Object o) =-    GitReference <$> o .: "object"-                 <*> o .: "url"-                 <*> o .: "ref"-  parseJSON _          = fail "Could not build a GitReference"--instance FromJSON GitObject where-  parseJSON (Object o) =-    GitObject <$> o .: "type"-           <*> o .: "sha"-           <*> o .: "url"-  parseJSON _          = fail "Could not build a GitObject"--instance FromJSON Issue where-  parseJSON (Object o) =-    Issue <$> o .:? "closed_at"-          <*> o .: "updated_at"-          <*> o .: "events_url"-          <*> o .: "html_url"-          <*> o .:? "closed_by"-          <*> o .: "labels"-          <*> o .: "number"-          <*> o .:? "assignee"-          <*> o .: "user"-          <*> o .: "title"-          <*> o .:? "pull_request"-          <*> o .: "url"-          <*> o .: "created_at"-          <*> o .: "body"-          <*> o .: "state"-          <*> o .: "id"-          <*> o .: "comments"-          <*> o .:? "milestone"-  parseJSON _          = fail "Could not build an Issue"--instance ToJSON NewIssue where-  toJSON (NewIssue t b a m ls) =-    object-    [ "title"     .= t-    , "body"      .= b-    , "assignee"  .= a-    , "milestone" .= m-    , "labels"    .= ls ]--instance ToJSON EditIssue where-  toJSON (EditIssue t b a s m ls) =-    object $ filter notNull $ [ "title" .= t-                              , "body" .= b-                              , "assignee" .= a-                              , "state" .= s-                              , "milestone" .= m-                              , "labels" .= ls ]-    where notNull (_, Null) = False-          notNull (_, _)    = True--instance FromJSON Milestone where-  parseJSON (Object o) =-    Milestone <$> o .: "creator"-              <*> o .: "due_on"-              <*> o .: "open_issues"-              <*> o .: "number"-              <*> o .: "closed_issues"-              <*> o .: "description"-              <*> o .: "title"-              <*> o .: "url"-              <*> o .: "created_at"-              <*> o .: "state"-  parseJSON _          = fail "Could not build a Milestone"--instance FromJSON IssueLabel where-  parseJSON (Object o) =-    IssueLabel <$> o .: "color"-               <*> o .: "url"-               <*> o .: "name"-  parseJSON _          = fail "Could not build a Milestone"--instance FromJSON PullRequestReference where-  parseJSON (Object o) =-    PullRequestReference <$> o .:? "html_url"-                         <*> o .:? "patch_url"-                         <*> o .:? "diff_url"-  parseJSON _          = fail "Could not build a PullRequest"--instance FromJSON IssueComment where-  parseJSON (Object o) =-    IssueComment <$> o .: "updated_at"-                 <*> o .: "user"-                 <*> o .: "url"-                 <*> o .: "created_at"-                 <*> o .: "body"-                 <*> o .: "id"-  parseJSON _          = fail "Could not build an IssueComment"--instance FromJSON Event where-  parseJSON (Object o) =-    Event <$> o .: "actor"-          <*> o .: "event"-          <*> o .:? "commit_id"-          <*> o .: "url"-          <*> o .: "created_at"-          <*> o .: "id"-          <*> o .:? "issue"-  parseJSON _          = fail "Could not build an Event"--instance FromJSON EventType where-  parseJSON (String "closed") = pure Closed-  parseJSON (String "reopened") = pure Reopened-  parseJSON (String "subscribed") = pure Subscribed-  parseJSON (String "merged") = pure Merged-  parseJSON (String "referenced") = pure Referenced-  parseJSON (String "mentioned") = pure Mentioned-  parseJSON (String "assigned") = pure Assigned-  parseJSON (String "unsubscribed") = pure Unsubscribed-  parseJSON (String "unassigned") = pure ActorUnassigned-  parseJSON (String "labeled") = pure Labeled-  parseJSON (String "unlabeled") = pure Unlabeled-  parseJSON (String "milestoned") = pure Milestoned-  parseJSON (String "demilestoned") = pure Demilestoned-  parseJSON (String "renamed") = pure Renamed-  parseJSON (String "locked") = pure Locked-  parseJSON (String "unlocked") = pure Unlocked-  parseJSON (String "head_ref_deleted") = pure HeadRefDeleted-  parseJSON (String "head_ref_restored") = pure HeadRefRestored-  parseJSON _ = fail "Could not build an EventType"--instance FromJSON SimpleOrganization where-  parseJSON (Object o) =-    SimpleOrganization <$> o .: "url"-                       <*> o .: "avatar_url"-                       <*> o .: "id"-                       <*> o .: "login"-  parseJSON _ = fail "Could not build a SimpleOrganization"--instance FromJSON Organization where-  parseJSON (Object o) =-    Organization <$> o .: "type"-                 <*> o .:? "blog"-                 <*> o .:? "location"-                 <*> o .: "login"-                 <*> o .: "followers"-                 <*> o .:? "company"-                 <*> o .: "avatar_url"-                 <*> o .: "public_gists"-                 <*> o .: "html_url"-                 <*> o .:? "email"-                 <*> o .: "following"-                 <*> o .: "public_repos"-                 <*> o .: "url"-                 <*> o .: "created_at"-                 <*> o .:? "name"-                 <*> o .: "id"-  parseJSON _ = fail "Could not build an Organization"--instance FromJSON PullRequest where-  parseJSON (Object o) =-      PullRequest-        <$> o .:? "closed_at"-        <*> o .: "created_at"-        <*> o .: "user"-        <*> o .: "patch_url"-        <*> o .: "state"-        <*> o .: "number"-        <*> o .: "html_url"-        <*> o .: "updated_at"-        <*> o .: "body"-        <*> o .: "issue_url"-        <*> o .: "diff_url"-        <*> o .: "url"-        <*> o .: "_links"-        <*> o .:? "merged_at"-        <*> o .: "title"-        <*> o .: "id"-  parseJSON _ = fail "Could not build a PullRequest"--instance ToJSON EditPullRequestState where-  toJSON (EditPullRequestStateOpen) = String "open"-  toJSON (EditPullRequestStateClosed) = String "closed"--instance ToJSON EditPullRequest where-  toJSON (EditPullRequest t b s) =-    object $ filter notNull [ "title" .= t, "body" .= b, "state" .= s ]-    where notNull (_, Null) = False-          notNull (_, _) = True--instance ToJSON CreatePullRequest where-  toJSON (CreatePullRequest t b headPR basePR) =-    object [ "title" .= t, "body" .= b, "head" .= headPR, "base" .= basePR ]-  toJSON (CreatePullRequestIssue issueNum headPR basePR) =-    object [ "issue" .= issueNum, "head" .= headPR, "base" .= basePR]--instance FromJSON DetailedPullRequest where-  parseJSON (Object o) =-      DetailedPullRequest-        <$> o .:? "closed_at"-        <*> o .: "created_at"-        <*> o .: "user"-        <*> o .: "patch_url"-        <*> o .: "state"-        <*> o .: "number"-        <*> o .: "html_url"-        <*> o .: "updated_at"-        <*> o .: "body"-        <*> o .: "issue_url"-        <*> o .: "diff_url"-        <*> o .: "url"-        <*> o .: "_links"-        <*> o .:? "merged_at"-        <*> o .: "title"-        <*> o .: "id"-        <*> o .:? "merged_by"-        <*> o .: "changed_files"-        <*> o .: "head"-        <*> o .: "comments"-        <*> o .: "deletions"-        <*> o .: "additions"-        <*> o .: "review_comments"-        <*> o .: "base"-        <*> o .: "commits"-        <*> o .: "merged"-        <*> o .:? "mergeable"-  parseJSON _ = fail "Could not build a DetailedPullRequest"--instance FromJSON PullRequestLinks where-  parseJSON (Object o) =-    PullRequestLinks <$> o <.:> ["review_comments", "href"]-                     <*> o <.:> ["comments", "href"]-                     <*> o <.:> ["html", "href"]-                     <*> o <.:> ["self", "href"]-  parseJSON _ = fail "Could not build a PullRequestLinks"--instance FromJSON PullRequestCommit where-  parseJSON (Object o) =-    PullRequestCommit <$> o .: "label"-                      <*> o .: "ref"-                      <*> o .: "sha"-                      <*> o .: "user"-                      <*> o .: "repo"-  parseJSON _ = fail "Could not build a PullRequestCommit"--instance FromJSON PullRequestEvent where-  parseJSON (Object o) =-    PullRequestEvent <$> o .: "action"-                     <*> o .: "number"-                     <*> o .: "pull_request"-                     <*> o .: "repository"-                     <*> o .: "sender"-  parseJSON _ = fail "Could not build a PullRequestEvent"--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 _ = fail "Could not build a PullRequestEventType"--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 "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"--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 (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"--instance FromJSON PingEvent where-  parseJSON (Object o) =-    PingEvent <$> o .: "zen"-              <*> o .: "hook"-              <*> o .: "hook_id"-  parseJSON _ = fail "Could not build a PingEvent"--instance FromJSON SearchReposResult where-  parseJSON (Object o) =-    SearchReposResult <$> o .: "total_count"-                      <*> o .:< "items"-  parseJSON _ = fail "Could not build a SearchReposResult"--instance FromJSON Repo where-  parseJSON (Object o) =-    Repo <$> o .:? "ssh_url"-         <*> o .: "description"-         <*> o .:? "created_at"-         <*> o .: "html_url"-         <*> o .:? "svn_url"-         <*> o .:? "forks"-         <*> o .:? "homepage"-         <*> o .: "fork"-         <*> o .:? "git_url"-         <*> o .: "private"-         <*> o .:? "clone_url"-         <*> o .:? "size"-         <*> o .:? "updated_at"-         <*> o .:? "watchers"-         <*> o .: "owner"-         <*> o .: "name"-         <*> o .:? "language"-         <*> o .:? "master_branch"-         <*> o .:? "pushed_at"-         <*> o .: "id"-         <*> o .: "url"-         <*> o .:? "open_issues"-         <*> o .:? "has_wiki"-         <*> o .:? "has_issues"-         <*> o .:? "has_downloads"-	 <*> o .:? "parent"-	 <*> o .:? "source"-         <*> o .: "hooks_url"-  parseJSON _ = fail "Could not build a Repo"--instance FromJSON SearchCodeResult where-  parseJSON (Object o) =-    SearchCodeResult <$> o .: "total_count"-                     <*> o .:< "items"-  parseJSON _ = fail "Could not build a SearchCodeResult"--instance FromJSON Code where-  parseJSON (Object o ) =-    Code <$> o .: "name"-         <*> o .: "path"-         <*> o .: "sha"-         <*> o .: "url"-         <*> o .: "git_url"-         <*> o .: "html_url"-         <*> o .: "repository"-  parseJSON _ = fail "Could not build a Code"--instance FromJSON RepoRef where-  parseJSON (Object o) =-    RepoRef <$> o .: "owner"-            <*> o .: "name"-  parseJSON _ = fail "Could not build a RepoRef"--instance FromJSON Contributor where-  parseJSON (Object o)-    | o `at` "type" == (Just "Anonymous") =-      AnonymousContributor <$> o .: "contributions"-                           <*> o .: "name"-    | otherwise =-      KnownContributor <$> o .: "contributions"-                       <*> o .: "avatar_url"-                       <*> o .: "login"-                       <*> o .: "url"-                       <*> o .: "id"-                       <*> o .: "gravatar_id"-  parseJSON _ = fail "Could not build a Contributor"--instance FromJSON Languages where-  parseJSON (Object o) =-    Languages <$>-      mapM (\name -> Language (T.unpack name) <$> o .: name)-           (Map.keys o)-  parseJSON _ = fail "Could not build Languages"--instance FromJSON Tag where-  parseJSON (Object o) =-    Tag <$> o .: "name"-        <*> o .: "zipball_url"-        <*> o .: "tarball_url"-        <*> o .: "commit"-  parseJSON _ = fail "Could not build a Tag"--instance FromJSON Branch where-  parseJSON (Object o) = Branch <$> o .: "name" <*> o .: "commit"-  parseJSON _ = fail "Could not build a Branch"--instance FromJSON BranchCommit where-  parseJSON (Object o) = BranchCommit <$> o .: "sha" <*> o .: "url"-  parseJSON _ = fail "Could not build a BranchCommit"--instance FromJSON DetailedOwner where-  parseJSON (Object o)-    | o `at` "gravatar_id" == Nothing =-      DetailedOrganization <$> o .: "created_at"-                   <*> o .: "type"-                   <*> o .: "public_gists"-                   <*> o .: "avatar_url"-                   <*> o .: "followers"-                   <*> o .: "following"-                   <*> o .:? "blog"-                   <*> o .:? "bio"-                   <*> o .: "public_repos"-                   <*> o .:? "name"-                   <*> o .:? "location"-                   <*> o .:? "company"-                   <*> o .: "url"-                   <*> o .: "id"-                   <*> o .: "html_url"-                   <*> o .: "login"-    | otherwise =-      DetailedUser <$> o .: "created_at"-                   <*> o .: "type"-                   <*> o .: "public_gists"-                   <*> o .: "avatar_url"-                   <*> o .: "followers"-                   <*> o .: "following"-                   <*> o .:? "hireable"-                   <*> o .: "gravatar_id"-                   <*> o .:? "blog"-                   <*> o .:? "bio"-                   <*> o .: "public_repos"-                   <*> o .:? "name"-                   <*> o .:? "location"-                   <*> o .:? "company"-                   <*> o .:? "email"-                   <*> o .: "url"-                   <*> o .: "id"-                   <*> o .: "html_url"-                   <*> o .: "login"-  parseJSON _ = fail "Could not build a DetailedOwner"--instance FromJSON RepoWebhook where-  parseJSON (Object o) =-    RepoWebhook <$> o .: "url"-                <*> o .: "test_url"-                <*> o .: "id"-                <*> o .: "name"-                <*> o .: "active"-                <*> o .: "events"-                <*> o .: "config"-                <*> o .: "last_response"-                <*> o .: "updated_at"-                <*> o .: "created_at"-  parseJSON _          = fail "Could not build a RepoWebhook"--instance FromJSON RepoWebhookResponse where-  parseJSON (Object o) =-    RepoWebhookResponse <$> o .: "code"-                        <*> o .: "status"-                        <*> o .: "message"-  parseJSON _          = fail "Could not build a RepoWebhookResponse"--instance FromJSON Content where-  parseJSON o@(Object _) = ContentFile <$> parseJSON o-  parseJSON (Array os) = ContentDirectory <$> (mapM parseJSON $ V.toList os)-  parseJSON _ = fail "Could not build a Content"--instance FromJSON ContentData where-  parseJSON (Object o) =-    ContentData <$> o .: "type"-                <*> o .: "encoding"-                <*> o .: "size"-                <*> o .: "name"-                <*> o .: "path"-                <*> o .: "content"-                <*> o .: "sha"-                <*> o .: "url"-                <*> o .: "git_url"-                <*> o .: "html_url"-  parseJSON _ = fail "Could not build a ContentData"---- | A slightly more generic version of Aeson's @(.:?)@, using `mzero' instead--- of `Nothing'.-(.:<) :: (FromJSON a) => Object -> T.Text -> Parser [a]-obj .:< key = case Map.lookup key obj of-                   Nothing -> pure mzero-                   Just v  -> parseJSON v---- | Produce all values for the given key.-values :: (Eq k, Hashable k, FromJSON v) => Map.HashMap k Value -> k -> Parser v-obj `values` key =-  let (Object children) = findWithDefault (Object Map.empty) key obj in-    parseJSON $ Array $ V.fromList $ Map.elems children---- | Produce the value for the last key by traversing.-(<.:>) :: (FromJSON v) => Object -> [T.Text] -> Parser v-obj <.:> [key] = obj .: key-obj <.:> (key:keys) =-  let (Object nextObj) = findWithDefault (Object Map.empty) key obj in-      nextObj <.:> keys-_ <.:> [] = fail "must have a pair"---- | Produce the value for the given key, maybe.-at :: Object -> T.Text -> Maybe Value-obj `at` key = Map.lookup key obj---- Taken from Data.Map:-findWithDefault :: (Eq k, Hashable k) => v -> k -> Map.HashMap k v -> v-findWithDefault def k m =-  case Map.lookup k m of-    Nothing -> def-    Just x  -> x
− Github/Data/Definitions.hs
@@ -1,624 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}--module Github.Data.Definitions where--import Data.Time-import Data.Data-import qualified Control.Exception as E-import qualified Data.Map as M---- | Errors have been tagged according to their source, so you can more easily--- dispatch and handle them.-data Error =-    HTTPConnectionError E.SomeException -- ^ A HTTP error occurred. The actual caught error is included.-  | ParseError String -- ^ An error in the parser itself.-  | JsonError String -- ^ The JSON is malformed or unexpected.-  | UserError String -- ^ Incorrect input.-  deriving Show---- | A date in the Github format, which is a special case of ISO-8601.-newtype GithubDate = GithubDate { fromGithubDate :: UTCTime }-  deriving (Show, Data, Typeable, Eq, Ord)--data Commit = Commit {-   commitSha       :: String-  ,commitParents   :: [Tree]-  ,commitUrl       :: String-  ,commitGitCommit :: GitCommit-  ,commitCommitter :: Maybe GithubOwner-  ,commitAuthor    :: Maybe GithubOwner-  ,commitFiles     :: [File]-  ,commitStats     :: Maybe Stats-} deriving (Show, Data, Typeable, Eq, Ord)--data Tree = Tree {-   treeSha :: String-  ,treeUrl :: String-  ,treeGitTrees :: [GitTree]-} deriving (Show, Data, Typeable, Eq, Ord)--data GitTree = GitTree {-  gitTreeType :: String-  ,gitTreeSha :: String-  -- Can be empty for submodule-  ,gitTreeUrl :: Maybe String-  ,gitTreeSize :: Maybe Int-  ,gitTreePath :: String-  ,gitTreeMode :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data GitCommit = GitCommit {-   gitCommitMessage :: String-  ,gitCommitUrl :: String-  ,gitCommitCommitter :: GitUser-  ,gitCommitAuthor :: GitUser-  ,gitCommitTree :: Tree-  ,gitCommitSha :: Maybe String-  ,gitCommitParents :: [Tree]-} deriving (Show, Data, Typeable, Eq, Ord)--data GithubOwner = GithubUser {-   githubOwnerAvatarUrl :: String-  ,githubOwnerLogin :: String-  ,githubOwnerUrl :: String-  ,githubOwnerId :: Int-  ,githubOwnerGravatarId :: Maybe String-  }-  | GithubOrganization {-   githubOwnerAvatarUrl :: String-  ,githubOwnerLogin :: String-  ,githubOwnerUrl :: String-  ,githubOwnerId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data GitUser = GitUser {-   gitUserName  :: String-  ,gitUserEmail :: String-  ,gitUserDate  :: GithubDate-} deriving (Show, Data, Typeable, Eq, Ord)--data File = File {-   fileBlobUrl :: String-  ,fileStatus :: String-  ,fileRawUrl :: String-  ,fileAdditions :: Int-  ,fileSha :: String-  ,fileChanges :: Int-  ,filePatch :: String-  ,fileFilename :: String-  ,fileDeletions :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data Stats = Stats {-   statsAdditions :: Int-  ,statsTotal :: Int-  ,statsDeletions :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data Comment = Comment {-   commentPosition :: Maybe Int-  ,commentLine :: Maybe Int-  ,commentBody :: String-  ,commentCommitId :: Maybe String-  ,commentUpdatedAt :: UTCTime-  ,commentHtmlUrl :: Maybe String-  ,commentUrl :: String-  ,commentCreatedAt :: Maybe UTCTime-  ,commentPath :: Maybe String-  ,commentUser :: GithubOwner-  ,commentId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data NewComment = NewComment {-   newCommentBody :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data EditComment = EditComment {-   editCommentBody :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data Diff = Diff {-   diffStatus :: String-  ,diffBehindBy :: Int-  ,diffPatchUrl :: String-  ,diffUrl :: String-  ,diffBaseCommit :: Commit-  ,diffCommits :: [Commit]-  ,diffTotalCommits :: Int-  ,diffHtmlUrl :: String-  ,diffFiles :: [File]-  ,diffAheadBy :: Int-  ,diffDiffUrl :: String-  ,diffPermalinkUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data Gist = Gist {-   gistUser :: GithubOwner-  ,gistGitPushUrl :: String-  ,gistUrl :: String-  ,gistDescription :: Maybe String-  ,gistCreatedAt :: GithubDate-  ,gistPublic :: Bool-  ,gistComments :: Int-  ,gistUpdatedAt :: GithubDate-  ,gistHtmlUrl :: String-  ,gistId :: String-  ,gistFiles :: [GistFile]-  ,gistGitPullUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data GistFile = GistFile {-   gistFileType :: String-  ,gistFileRawUrl :: String-  ,gistFileSize :: Int-  ,gistFileLanguage :: Maybe String-  ,gistFileFilename :: String-  ,gistFileContent :: Maybe String-} deriving (Show, Data, Typeable, Eq, Ord)--data GistComment = GistComment {-   gistCommentUser :: GithubOwner-  ,gistCommentUrl :: String-  ,gistCommentCreatedAt :: GithubDate-  ,gistCommentBody :: String-  ,gistCommentUpdatedAt :: GithubDate-  ,gistCommentId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data Blob = Blob {-   blobUrl :: String-  ,blobEncoding :: String-  ,blobContent :: String-  ,blobSha :: String-  ,blobSize :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data NewGitReference = NewGitReference {-   newGitReferenceRef :: String-  ,newGitReferenceSha :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data GitReference = GitReference {-   gitReferenceObject :: GitObject-  ,gitReferenceUrl :: String-  ,gitReferenceRef :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data GitObject = GitObject {-   gitObjectType :: String-  ,gitObjectSha :: String-  ,gitObjectUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data Issue = Issue {-   issueClosedAt :: Maybe GithubDate-  ,issueUpdatedAt :: GithubDate-  ,issueEventsUrl :: String-  ,issueHtmlUrl :: Maybe String-  ,issueClosedBy :: Maybe GithubOwner-  ,issueLabels :: [IssueLabel]-  ,issueNumber :: Int-  ,issueAssignee :: Maybe GithubOwner-  ,issueUser :: GithubOwner-  ,issueTitle :: String-  ,issuePullRequest :: Maybe PullRequestReference-  ,issueUrl :: String-  ,issueCreatedAt :: GithubDate-  ,issueBody :: Maybe String-  ,issueState :: String-  ,issueId :: Int-  ,issueComments :: Int-  ,issueMilestone :: Maybe Milestone-} deriving (Show, Data, Typeable, Eq, Ord)--data NewIssue = NewIssue {-  newIssueTitle :: String-, newIssueBody :: Maybe String-, newIssueAssignee :: Maybe String-, newIssueMilestone :: Maybe Int-, newIssueLabels :: Maybe [String]-} deriving (Show, Data, Typeable, Eq, Ord)--data EditIssue = EditIssue {-  editIssueTitle :: Maybe String-, editIssueBody :: Maybe String-, editIssueAssignee :: Maybe String-, editIssueState :: Maybe String-, editIssueMilestone :: Maybe Int-, editIssueLabels :: Maybe [String]-} deriving  (Show, Data, Typeable, Eq, Ord)---data Milestone = Milestone {-   milestoneCreator :: GithubOwner-  ,milestoneDueOn :: Maybe GithubDate-  ,milestoneOpenIssues :: Int-  ,milestoneNumber :: Int-  ,milestoneClosedIssues :: Int-  ,milestoneDescription :: Maybe String-  ,milestoneTitle :: String-  ,milestoneUrl :: String-  ,milestoneCreatedAt :: GithubDate-  ,milestoneState :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data IssueLabel = IssueLabel {-   labelColor :: String-  ,labelUrl :: String-  ,labelName :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data PullRequestReference = PullRequestReference {-  pullRequestReferenceHtmlUrl :: Maybe String-  ,pullRequestReferencePatchUrl :: Maybe String-  ,pullRequestReferenceDiffUrl :: Maybe String-} deriving (Show, Data, Typeable, Eq, Ord)--data IssueComment = IssueComment {-   issueCommentUpdatedAt :: GithubDate-  ,issueCommentUser :: GithubOwner-  ,issueCommentUrl :: String-  ,issueCommentCreatedAt :: GithubDate-  ,issueCommentBody :: String-  ,issueCommentId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)---- | Data describing an @Event@.-data EventType =-    Mentioned     -- ^ The actor was @mentioned in an issue body.-  | Subscribed    -- ^ The actor subscribed to receive notifications for an issue.-  | Unsubscribed  -- ^ The issue was unsubscribed from by the actor.-  | Referenced    -- ^ The issue was referenced from a commit message. The commit_id attribute is the commit SHA1 of where that happened.-  | Merged        -- ^ The issue was merged by the actor. The commit_id attribute is the SHA1 of the HEAD commit that was merged.-  | Assigned      -- ^ The issue was assigned to the actor.-  | Closed        -- ^ The issue was closed by the actor. When the commit_id is present, it identifies the commit that closed the issue using “closes / fixes #NN” syntax. -  | Reopened      -- ^ The issue was reopened by the actor.-  | ActorUnassigned    -- ^ The issue was unassigned to the actor-  | Labeled       -- ^ A label was added to the issue.-  | Unlabeled     -- ^ A label was removed from the issue.-  | Milestoned    -- ^ The issue was added to a milestone.-  | Demilestoned  -- ^ The issue was removed from a milestone.-  | Renamed       -- ^ The issue title was changed.-  | Locked        -- ^ The issue was locked by the actor.-  | Unlocked      -- ^ The issue was unlocked by the actor.-  | HeadRefDeleted -- ^ The pull request’s branch was deleted.-  | HeadRefRestored -- ^ The pull request’s branch was restored.-  deriving (Show, Data, Typeable, Eq, Ord)--data Event = Event {-   eventActor :: GithubOwner-  ,eventType :: EventType-  ,eventCommitId :: Maybe String-  ,eventUrl :: String-  ,eventCreatedAt :: GithubDate-  ,eventId :: Int-  ,eventIssue :: Maybe Issue-} deriving (Show, Data, Typeable, Eq, Ord)--data SimpleOrganization = SimpleOrganization {-   simpleOrganizationUrl :: String-  ,simpleOrganizationAvatarUrl :: String-  ,simpleOrganizationId :: Int-  ,simpleOrganizationLogin :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data Organization = Organization {-   organizationType :: String-  ,organizationBlog :: Maybe String-  ,organizationLocation :: Maybe String-  ,organizationLogin :: String-  ,organizationFollowers :: Int-  ,organizationCompany :: Maybe String-  ,organizationAvatarUrl :: String-  ,organizationPublicGists :: Int-  ,organizationHtmlUrl :: String-  ,organizationEmail :: Maybe String-  ,organizationFollowing :: Int-  ,organizationPublicRepos :: Int-  ,organizationUrl :: String-  ,organizationCreatedAt :: GithubDate-  ,organizationName :: Maybe String-  ,organizationId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data PullRequest = PullRequest {-   pullRequestClosedAt :: Maybe GithubDate-  ,pullRequestCreatedAt :: GithubDate-  ,pullRequestUser :: GithubOwner-  ,pullRequestPatchUrl :: String-  ,pullRequestState :: String-  ,pullRequestNumber :: Int-  ,pullRequestHtmlUrl :: String-  ,pullRequestUpdatedAt :: GithubDate-  ,pullRequestBody :: String-  ,pullRequestIssueUrl :: String-  ,pullRequestDiffUrl :: String-  ,pullRequestUrl :: String-  ,pullRequestLinks :: PullRequestLinks-  ,pullRequestMergedAt :: Maybe GithubDate-  ,pullRequestTitle :: String-  ,pullRequestId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data DetailedPullRequest = DetailedPullRequest {-  -- this is a duplication of a PullRequest-   detailedPullRequestClosedAt :: Maybe GithubDate-  ,detailedPullRequestCreatedAt :: GithubDate-  ,detailedPullRequestUser :: GithubOwner-  ,detailedPullRequestPatchUrl :: String-  ,detailedPullRequestState :: String-  ,detailedPullRequestNumber :: Int-  ,detailedPullRequestHtmlUrl :: String-  ,detailedPullRequestUpdatedAt :: GithubDate-  ,detailedPullRequestBody :: String-  ,detailedPullRequestIssueUrl :: String-  ,detailedPullRequestDiffUrl :: String-  ,detailedPullRequestUrl :: String-  ,detailedPullRequestLinks :: PullRequestLinks-  ,detailedPullRequestMergedAt :: Maybe GithubDate-  ,detailedPullRequestTitle :: String-  ,detailedPullRequestId :: Int--  ,detailedPullRequestMergedBy :: Maybe GithubOwner-  ,detailedPullRequestChangedFiles :: Int-  ,detailedPullRequestHead :: PullRequestCommit-  ,detailedPullRequestComments :: Int-  ,detailedPullRequestDeletions :: Int-  ,detailedPullRequestAdditions :: Int-  ,detailedPullRequestReviewComments :: Int-  ,detailedPullRequestBase :: PullRequestCommit-  ,detailedPullRequestCommits :: Int-  ,detailedPullRequestMerged :: Bool-  ,detailedPullRequestMergeable :: Maybe Bool-} deriving (Show, Data, Typeable, Eq, Ord)--data EditPullRequest = EditPullRequest {-   editPullRequestTitle :: Maybe String-  ,editPullRequestBody :: Maybe String-  ,editPullRequestState :: Maybe EditPullRequestState-} deriving (Show)--data CreatePullRequest =-      CreatePullRequest-      { createPullRequestTitle :: String-      , createPullRequestBody  :: String-      , createPullRequestHead  :: String-      , createPullRequestBase  :: String-      }-    | CreatePullRequestIssue-      { createPullRequestIssueNum :: Int-      , createPullRequestHead     :: String-      , createPullRequestBase     :: String-      }-    deriving (Show)--data PullRequestLinks = PullRequestLinks {-   pullRequestLinksReviewComments :: String-  ,pullRequestLinksComments :: String-  ,pullRequestLinksHtml :: String-  ,pullRequestLinksSelf :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data PullRequestCommit = PullRequestCommit {-   pullRequestCommitLabel :: String-  ,pullRequestCommitRef :: String-  ,pullRequestCommitSha :: String-  ,pullRequestCommitUser :: GithubOwner-  ,pullRequestCommitRepo :: Repo-} deriving (Show, Data, Typeable, Eq, Ord)--data SearchReposResult = SearchReposResult {-  searchReposTotalCount :: Int-  ,searchReposRepos :: [Repo]-} deriving (Show, Data, Typeable, Eq, Ord)--data Repo = Repo {-   repoSshUrl :: Maybe String-  ,repoDescription :: Maybe String-  ,repoCreatedAt :: Maybe GithubDate-  ,repoHtmlUrl :: String-  ,repoSvnUrl :: Maybe String-  ,repoForks :: Maybe Int-  ,repoHomepage :: Maybe String-  ,repoFork :: Maybe Bool-  ,repoGitUrl :: Maybe String-  ,repoPrivate :: Bool-  ,repoCloneUrl :: Maybe String-  ,repoSize :: Maybe Int-  ,repoUpdatedAt :: Maybe GithubDate-  ,repoWatchers :: Maybe Int-  ,repoOwner :: GithubOwner-  ,repoName :: String-  ,repoLanguage :: Maybe String-  ,repoMasterBranch :: Maybe String-  ,repoPushedAt :: Maybe GithubDate   -- ^ this is Nothing for new repositories-  ,repoId :: Int-  ,repoUrl :: String-  ,repoOpenIssues :: Maybe Int-  ,repoHasWiki :: Maybe Bool-  ,repoHasIssues :: Maybe Bool-  ,repoHasDownloads :: Maybe Bool-  ,repoParent :: Maybe RepoRef-  ,repoSource :: Maybe RepoRef-  ,repoHooksUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data RepoRef = RepoRef GithubOwner String -- Repo owner and name- deriving (Show, Data, Typeable, Eq, Ord)--data SearchCodeResult = SearchCodeResult {-  searchCodeTotalCount :: Int-  ,searchCodeCodes :: [Code]-} deriving (Show, Data, Typeable, Eq, Ord)--data Code = Code {-   codeName :: String-  ,codePath :: String-  ,codeSha :: String-  ,codeUrl :: String-  ,codeGitUrl :: String-  ,codeHtmlUrl :: String-  ,codeRepo :: Repo-} deriving (Show, Data, Typeable, Eq, Ord)--data Content = ContentFile ContentData | ContentDirectory [ContentData]- deriving (Show, Data, Typeable, Eq, Ord)--data ContentData = ContentData {-   contentType :: String-  ,contentEncoding :: String-  ,contentSize :: Int-  ,contentName :: String-  ,contentPath :: String-  ,contentData :: String-  ,contentSha :: String-  ,contentUrl :: String-  ,contentGitUrl :: String-  ,contentHtmlUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data Contributor-  -- | An existing Github user, with their number of contributions, avatar-  -- URL, login, URL, ID, and Gravatar ID.-  = KnownContributor Int String String String Int String-  -- | An unknown Github user with their number of contributions and recorded name.-  | AnonymousContributor Int String- deriving (Show, Data, Typeable, Eq, Ord)---- | This is only used for the FromJSON instance.-data Languages = Languages { getLanguages :: [Language] }-  deriving (Show, Data, Typeable, Eq, Ord)---- | A programming language with the name and number of characters written in--- it.-data Language = Language String Int- deriving (Show, Data, Typeable, Eq, Ord)--data Tag = Tag {-   tagName :: String-  ,tagZipballUrl :: String-  ,tagTarballUrl :: String-  ,tagCommit :: BranchCommit-} deriving (Show, Data, Typeable, Eq, Ord)--data Branch = Branch {-   branchName :: String-  ,branchCommit :: BranchCommit-} deriving (Show, Data, Typeable, Eq, Ord)--data BranchCommit = BranchCommit {-   branchCommitSha :: String-  ,branchCommitUrl :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data DetailedOwner = DetailedUser {-   detailedOwnerCreatedAt :: GithubDate-  ,detailedOwnerType :: String-  ,detailedOwnerPublicGists :: Int-  ,detailedOwnerAvatarUrl :: String-  ,detailedOwnerFollowers :: Int-  ,detailedOwnerFollowing :: Int-  ,detailedOwnerHireable :: Maybe Bool-  ,detailedOwnerGravatarId :: Maybe String-  ,detailedOwnerBlog :: Maybe String-  ,detailedOwnerBio :: Maybe String-  ,detailedOwnerPublicRepos :: Int-  ,detailedOwnerName :: Maybe String-  ,detailedOwnerLocation :: Maybe String-  ,detailedOwnerCompany :: Maybe String-  ,detailedOwnerEmail :: Maybe String-  ,detailedOwnerUrl :: String-  ,detailedOwnerId :: Int-  ,detailedOwnerHtmlUrl :: String-  ,detailedOwnerLogin :: String-  }-  | DetailedOrganization {-   detailedOwnerCreatedAt :: GithubDate-  ,detailedOwnerType :: String-  ,detailedOwnerPublicGists :: Int-  ,detailedOwnerAvatarUrl :: String-  ,detailedOwnerFollowers :: Int-  ,detailedOwnerFollowing :: Int-  ,detailedOwnerBlog :: Maybe String-  ,detailedOwnerBio :: Maybe String-  ,detailedOwnerPublicRepos :: Int-  ,detailedOwnerName :: Maybe String-  ,detailedOwnerLocation :: Maybe String-  ,detailedOwnerCompany :: Maybe String-  ,detailedOwnerUrl :: String-  ,detailedOwnerId :: Int-  ,detailedOwnerHtmlUrl :: String-  ,detailedOwnerLogin :: String-} deriving (Show, Data, Typeable, Eq, Ord)--data RepoWebhook = RepoWebhook {-   repoWebhookUrl :: String-  ,repoWebhookTestUrl :: String-  ,repoWebhookId :: Integer-  ,repoWebhookName :: String-  ,repoWebhookActive :: Bool-  ,repoWebhookEvents :: [RepoWebhookEvent]-  ,repoWebhookConfig :: M.Map String String-  ,repoWebhookLastResponse :: RepoWebhookResponse-  ,repoWebhookUpdatedAt :: GithubDate-  ,repoWebhookCreatedAt :: GithubDate-} deriving (Show, Data, Typeable, Eq, Ord)--data RepoWebhookEvent =-   WebhookWildcardEvent- | WebhookCommitCommentEvent- | WebhookCreateEvent- | WebhookDeleteEvent- | WebhookDeploymentEvent- | WebhookDeploymentStatusEvent- | WebhookForkEvent- | WebhookGollumEvent- | WebhookIssueCommentEvent- | WebhookIssuesEvent- | WebhookMemberEvent- | WebhookPageBuildEvent- | WebhookPublicEvent- | WebhookPullRequestReviewCommentEvent- | WebhookPullRequestEvent- | WebhookPushEvent- | WebhookReleaseEvent- | WebhookStatusEvent- | WebhookTeamAddEvent- | WebhookWatchEvent-   deriving (Show, Data, Typeable, Eq, Ord)--data RepoWebhookResponse = RepoWebhookResponse {-   repoWebhookResponseCode :: Maybe Int-  ,repoWebhookResponseStatus :: String-  ,repoWebhookResponseMessage :: Maybe String-} deriving (Show, Data, Typeable, Eq, Ord)--data PullRequestEvent = PullRequestEvent {-   pullRequestEventAction :: PullRequestEventType-  ,pullRequestEventNumber :: Int-  ,pullRequestEventPullRequest :: DetailedPullRequest-  ,pullRequestRepository :: Repo-  ,pullRequestSender :: GithubOwner-} deriving (Show, Data, Typeable, Eq, Ord)--data PullRequestEventType =-    PullRequestOpened-  | PullRequestClosed-  | PullRequestSynchronized-  | PullRequestReopened-  | PullRequestAssigned-  | PullRequestUnassigned-  | PullRequestLabeled-  | PullRequestUnlabeled-  deriving (Show, Data, Typeable, Eq, Ord)--data PingEvent = PingEvent {-   pingEventZen :: String-  ,pingEventHook :: RepoWebhook-  ,pingEventHookId :: Int-} deriving (Show, Data, Typeable, Eq, Ord)--data EditPullRequestState =-    EditPullRequestStateOpen-  | EditPullRequestStateClosed-  deriving Show
− Github/Events.hs
@@ -1,13 +0,0 @@-module Github.Events (- parseEvent-) where--import qualified Data.ByteString.Lazy.Char8 as LBS--import Data.Aeson (FromJSON)--import Github.Data.Definitions (Error(..))-import Github.Private (parseJson)--parseEvent :: (FromJSON b, Show b) => LBS.ByteString -> Either Error b-parseEvent = parseJson
− Github/Gists.hs
@@ -1,35 +0,0 @@--- | The gists API as described at <http://developer.github.com/v3/gists/>.-module Github.Gists (- gists-,gists'-,gist-,gist'-,module Github.Data-) where--import Github.Data-import Github.Private---- | The list of all gists created by the user --- --- > gists' (Just ("github-username", "github-password")) "mike-burns"-gists' :: Maybe GithubAuth -> String -> IO (Either Error [Gist])-gists' auth userName = githubGet' auth ["users", userName, "gists"]---- | The list of all public gists created by the user.------ > gists "mike-burns"-gists :: String -> IO (Either Error [Gist])-gists = gists' Nothing---- | A specific gist, given its id, with authentication credentials------ > gist' (Just ("github-username", "github-password")) "225074"-gist' :: Maybe GithubAuth -> String -> IO (Either Error Gist)-gist' auth reqGistId = githubGet' auth ["gists", reqGistId]---- | A specific gist, given its id.------ > gist "225074"-gist :: String -> IO (Either Error Gist)-gist = gist' Nothing
− Github/Gists/Comments.hs
@@ -1,22 +0,0 @@--- | The loving comments people have left on Gists, described on--- <http://developer.github.com/v3/gists/comments/>.-module Github.Gists.Comments (- commentsOn-,comment-,module Github.Data-) where--import Github.Data-import Github.Private---- | All the comments on a Gist, given the Gist ID.------ > commentsOn "1174060"-commentsOn :: String -> IO (Either Error [GistComment])-commentsOn reqGistId = githubGet ["gists", reqGistId, "comments"]---- | A specific comment, by the comment ID.------ > comment "62449"-comment :: String -> IO (Either Error GistComment)-comment reqCommentId = githubGet ["gists", "comments", reqCommentId]
− Github/GitData/Blobs.hs
@@ -1,16 +0,0 @@--- | The API for dealing with git blobs from Github repos, as described in--- <http://developer.github.com/v3/git/blobs/>.-module Github.GitData.Blobs (- blob-,module Github.Data-) where--import Github.Data-import Github.Private---- | Get a blob by SHA1.------ > blob "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-blob :: String -> String -> String -> IO (Either Error Blob)-blob user reqRepoName sha =-  githubGet ["repos", user, reqRepoName, "git", "blobs", sha]
− Github/GitData/Commits.hs
@@ -1,16 +0,0 @@--- | The API for underlying git commits of a Github repo, as described on--- <http://developer.github.com/v3/git/commits/>.-module Github.GitData.Commits (- commit-,module Github.Data-) where--import Github.Data-import Github.Private---- | A single commit, by SHA1.------ > commit "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-commit :: String -> String -> String -> IO (Either Error GitCommit)-commit user reqRepoName sha =-  githubGet ["repos", user, reqRepoName, "git", "commits", sha]
− Github/GitData/References.hs
@@ -1,38 +0,0 @@--- | 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.GitData.References (- reference-,references-,createReference-,namespacedReferences-,module Github.Data-) where--import Github.Data-import Github.Private---- | A single reference by the ref name.------ > reference "mike-burns" "github" "heads/master"-reference :: String -> String -> String -> IO (Either Error GitReference)-reference user reqRepoName ref =-  githubGet ["repos", user, reqRepoName, "git", "refs", ref]---- | The history of references for a repo.------ > references "mike-burns" "github"-references :: String -> String -> IO (Either Error [GitReference])-references user reqRepoName =-  githubGet ["repos", user, reqRepoName, "git", "refs"]--createReference :: GithubAuth -> String -> String -> NewGitReference -> IO (Either Error GitReference)-createReference auth owner reqRepoName newRef =-  githubPost auth ["repos", owner, reqRepoName, "git", "refs"] newRef---- | Limited references by a namespace.------ > namespacedReferences "thoughtbot" "paperclip" "tags"-namespacedReferences :: String -> String -> String -> IO (Either Error [GitReference])-namespacedReferences user reqRepoName namespace =-  githubGet ["repos", user, reqRepoName, "git", "refs", namespace]
− Github/GitData/Trees.hs
@@ -1,37 +0,0 @@--- | 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.GitData.Trees (- tree-,nestedTree-,module Github.Data-) where--import Github.Data-import Github.Private---- | A tree for a SHA1.------ > tree (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-tree' :: Maybe GithubAuth -> String -> String -> String -> IO (Either Error Tree)-tree' auth user reqRepoName sha =-  githubGet' auth ["repos", user, reqRepoName, "git", "trees", sha]---- | A tree for a SHA1.------ > tree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-tree :: String -> String -> String -> IO (Either Error Tree)-tree = tree' Nothing---- | A recursively-nested tree for a SHA1.------ > nestedTree' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-nestedTree' :: Maybe GithubAuth -> String -> String -> String -> IO (Either Error Tree)-nestedTree' auth user reqRepoName sha =-  githubGetWithQueryString' auth ["repos", user, reqRepoName, "git", "trees", sha]-                                 "recursive=1"---- | A recursively-nested tree for a SHA1.------ > nestedTree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-nestedTree :: String -> String -> String -> IO (Either Error Tree)-nestedTree = nestedTree' Nothing
− Github/Issues.hs
@@ -1,129 +0,0 @@-{-# LANGUAGE CPP, OverloadedStrings #-}--- | The issues API as described on <http://developer.github.com/v3/issues/>.-module Github.Issues (- issue-,issue'-,issuesForRepo-,issuesForRepo'-,IssueLimitation(..)-,createIssue-,newIssue-,editIssue-,editOfIssue-,module Github.Data-) where--import Github.Data-import Github.Private-import Data.List (intercalate)-#if MIN_VERSION_base(4, 8, 0)-import Data.Time (defaultTimeLocale)-#else-import System.Locale (defaultTimeLocale)-#endif--import Data.Time.Format (formatTime)-import Data.Time.Clock (UTCTime(..))---- | A data structure for describing how to filter issues. This is used by--- @issuesForRepo@.-data IssueLimitation =-      AnyMilestone -- ^ Issues appearing in any milestone. [default]-    | NoMilestone -- ^ Issues without a milestone.-    | MilestoneId Int -- ^ Only issues that are in the milestone with the given id.-    | Open -- ^ Only open issues. [default]-    | OnlyClosed -- ^ Only closed issues.-    | Unassigned -- ^ Issues to which no one has been assigned ownership.-    | AnyAssignment -- ^ All issues regardless of assignment. [default]-    | AssignedTo String -- ^ Only issues assigned to the user with the given login.-    | Mentions String -- ^ Issues which mention the given string, taken to be a user's login.-    | Labels [String] -- ^ A list of labels to filter by.-    | Ascending -- ^ Sort ascending.-    | Descending -- ^ Sort descending. [default]-    | Since UTCTime -- ^ Only issues created since the specified date and time.-    | PerPage Int -- ^ Download this many issues per query----- | 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 GithubAuth -> String -> String -> Int -> IO (Either Error Issue)-issue' auth user reqRepoName reqIssueNumber =-  githubGet' auth ["repos", user, reqRepoName, "issues", show reqIssueNumber]---- | Details on a specific issue, given the repo owner and name, and the issue--- number.------ > issue "thoughtbot" "paperclip" "462"-issue :: String -> String -> Int -> IO (Either Error Issue)-issue = issue' Nothing---- | All issues for a repo (given the repo owner and name), with optional--- restrictions as described in the @IssueLimitation@ data type.------ > issuesForRepo' (Just ("github-username", "github-password")) "thoughtbot" "paperclip" [NoMilestone, OnlyClosed, Mentions "jyurek", Ascending]-issuesForRepo' :: Maybe GithubAuth -> String -> String -> [IssueLimitation] -> IO (Either Error [Issue])-issuesForRepo' auth user reqRepoName issueLimitations =-  githubGetWithQueryString' -    auth-    ["repos", user, reqRepoName, "issues"]-    (queryStringFromLimitations issueLimitations)-  where-    queryStringFromLimitations = intercalate "&" . map convert--    convert AnyMilestone     = "milestone=*"-    convert NoMilestone      = "milestone=none"-    convert (MilestoneId n)  = "milestone=" ++ show n-    convert Open             = "state=open"-    convert OnlyClosed       = "state=closed"-    convert Unassigned       = "assignee=none"-    convert AnyAssignment    = "assignee=*"-    convert (AssignedTo u)   = "assignee=" ++ u-    convert (Mentions u)     = "mentioned=" ++ u-    convert (Labels l)       = "labels=" ++ intercalate "," l-    convert Ascending        = "direction=asc"-    convert Descending       = "direction=desc"-    convert (PerPage n)      = "per_page=" ++ show n-    convert (Since t)        =-      "since=" ++ formatTime defaultTimeLocale "%FT%TZ" t---- | All issues for a repo (given the repo owner and name), with optional--- restrictions as described in the @IssueLimitation@ data type.------ > issuesForRepo "thoughtbot" "paperclip" [NoMilestone, OnlyClosed, Mentions "jyurek", Ascending]-issuesForRepo :: String -> String -> [IssueLimitation] -> IO (Either Error [Issue])-issuesForRepo = issuesForRepo' Nothing----- Creating new issues.--newIssue :: String -> NewIssue-newIssue title = NewIssue title Nothing Nothing Nothing Nothing----- |--- Create a new issue.------ > createIssue (GithubUser (user, password)) user repo--- >  (newIssue "some_repo") {...}-createIssue :: GithubAuth -> String -> String -> NewIssue-            -> IO (Either Error Issue)-createIssue auth user repo = githubPost auth ["repos", user, repo, "issues"]----- Editing issues.--editOfIssue :: EditIssue-editOfIssue = EditIssue Nothing Nothing Nothing Nothing Nothing Nothing----- |--- Edit an issue.------ > editIssue (GithubUser (user, password)) user repo issue--- >  editOfIssue {...}-editIssue :: GithubAuth -> String -> String -> Int -> EditIssue-            -> IO (Either Error Issue)-editIssue auth user repo iss =-  githubPatch auth ["repos", user, repo, "issues", show iss]
− Github/Issues/Comments.hs
@@ -1,59 +0,0 @@--- | The Github issue comments API from--- <http://developer.github.com/v3/issues/comments/>.-module Github.Issues.Comments (- comment-,comments-,comments'-,createComment-,editComment-,module Github.Data-) where--import Github.Data-import Github.Private---- | A specific comment, by ID.------ > comment "thoughtbot" "paperclip" 1468184-comment :: String -> String -> Int -> IO (Either Error IssueComment)-comment user reqRepoName reqCommentId =-  githubGet ["repos", user, reqRepoName, "issues", "comments", show reqCommentId]---- | All comments on an issue, by the issue's number.------ > comments "thoughtbot" "paperclip" 635-comments :: String -> String -> Int -> IO (Either Error [IssueComment])-comments user reqRepoName reqIssueNumber =-  githubGet ["repos", user, reqRepoName, "issues", show reqIssueNumber, "comments"]---- | All comments on an issue, by the issue's number, using authentication.------ > comments' (GithubUser (user, password)) "thoughtbot" "paperclip" 635-comments' :: Maybe GithubAuth -> String -> String -> Int -> IO (Either Error [IssueComment])-comments' auth user reqRepoName reqIssueNumber =-  githubGet' auth ["repos", user, reqRepoName, "issues", show reqIssueNumber, "comments"]------ |--- Create a new comment.------ > createComment (GithubUser (user, password)) user repo issue--- >  "some words"-createComment :: GithubAuth -> String -> String -> Int -> String-            -> IO (Either Error Comment)-createComment auth user repo iss body =-  githubPost auth-  ["repos", user, repo, "issues", show iss, "comments"] (NewComment body)----- |--- Edit a comment.------ > editComment (GithubUser (user, password)) user repo commentid--- >  "new words"-editComment :: GithubAuth -> String -> String -> Int -> String-            -> IO (Either Error Comment)-editComment auth user repo commid body =-  githubPatch auth ["repos", user, repo, "issues", "comments", show commid]-  (EditComment body)
− Github/Issues/Events.hs
@@ -1,56 +0,0 @@--- | The Github issue events API, which is described on--- <http://developer.github.com/v3/issues/events/>-module Github.Issues.Events (- eventsForIssue-,eventsForIssue'-,eventsForRepo-,eventsForRepo'-,event-,event'-,module Github.Data-) where--import Github.Data-import Github.Private---- | All events that have happened on an issue.------ > eventsForIssue "thoughtbot" "paperclip" 49-eventsForIssue :: String -> String -> Int -> IO (Either Error [Event])-eventsForIssue user reqRepoName reqIssueNumber =-  githubGet ["repos", user, reqRepoName, "issues", show reqIssueNumber, "events"]---- | All events that have happened on an issue, using authentication.------ > eventsForIssue' (GithubUser (user, password)) "thoughtbot" "paperclip" 49-eventsForIssue' :: Maybe GithubAuth -> String -> String -> Int -> IO (Either Error [Event])-eventsForIssue' auth user reqRepoName reqIssueNumber =-  githubGet' auth ["repos", user, reqRepoName, "issues", show reqIssueNumber, "events"]---- | All the events for all issues in a repo.------ > eventsForRepo "thoughtbot" "paperclip"-eventsForRepo :: String -> String -> IO (Either Error [Event])-eventsForRepo user reqRepoName =-  githubGet ["repos", user, reqRepoName, "issues", "events"]---- | All the events for all issues in a repo, using authentication.------ > eventsForRepo' (GithubUser (user, password)) "thoughtbot" "paperclip"-eventsForRepo' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Event])-eventsForRepo' auth user reqRepoName =-  githubGet' auth ["repos", user, reqRepoName, "issues", "events"]---- | Details on a specific event, by the event's ID.------ > event "thoughtbot" "paperclip" 5335772-event :: String -> String -> Int -> IO (Either Error Event)-event user reqRepoName reqEventId =-  githubGet ["repos", user, reqRepoName, "issues", "events", show reqEventId]---- | Details on a specific event, by the event's ID, using authentication.------ > event' (GithubUser (user, password)) "thoughtbot" "paperclip" 5335772-event' :: Maybe GithubAuth -> String -> String -> Int -> IO (Either Error Event)-event' auth user reqRepoName reqEventId =-  githubGet' auth ["repos", user, reqRepoName, "issues", "events", show reqEventId]
− Github/Issues/Labels.hs
@@ -1,39 +0,0 @@--- | The API for dealing with labels on Github issues, as described on--- <http://developer.github.com/v3/issues/labels/>.-module Github.Issues.Labels (- label-,labelsOnRepo-,labelsOnIssue-,labelsOnMilestone-,module Github.Data-) where--import Github.Data-import Github.Private---- | All the labels available to use on any issue in the repo.------ > labelsOnRepo "thoughtbot" "paperclip"-labelsOnRepo :: String -> String -> IO (Either Error [IssueLabel])-labelsOnRepo user reqRepoName = githubGet ["repos", user, reqRepoName, "labels"]---- | The labels on an issue in a repo.------ > labelsOnIssue "thoughtbot" "paperclip" 585-labelsOnIssue :: String -> String -> Int ->  IO (Either Error [IssueLabel])-labelsOnIssue user reqRepoName reqIssueId =-  githubGet ["repos", user, reqRepoName, "issues", show reqIssueId, "labels"]---- | All the labels on a repo's milestone, given the milestone ID.------ > labelsOnMilestone "thoughtbot" "paperclip" 2-labelsOnMilestone :: String -> String -> Int ->  IO (Either Error [IssueLabel])-labelsOnMilestone user reqRepoName milestoneId =-  githubGet ["repos", user, reqRepoName, "milestones", show milestoneId, "labels"]---- | A label, by name.------ > Github.label "thoughtbot" "paperclip" "bug"-label :: String -> String -> String -> IO (Either Error IssueLabel)-label user reqRepoName reqLabelName =-  githubGet ["repos", user, reqRepoName, "labels", reqLabelName]
− Github/Issues/Milestones.hs
@@ -1,30 +0,0 @@--- | The milestones API as described on--- <http://developer.github.com/v3/issues/milestones/>.-module Github.Issues.Milestones (- milestones-,milestones'-,milestone-,module Github.Data-) where--import Github.Data-import Github.Private---- | All milestones in the repo.------ > milestones "thoughtbot" "paperclip"-milestones :: String -> String -> IO (Either Error [Milestone])-milestones = milestones' Nothing---- | All milestones in the repo, using authentication.------ > milestones' (GithubUser (user, password)) "thoughtbot" "paperclip"-milestones' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Milestone])-milestones' auth user reqRepoName = githubGet' auth ["repos", user, reqRepoName, "milestones"]---- | Details on a specific milestone, given it's milestone number.------ > milestone "thoughtbot" "paperclip" 2-milestone :: String -> String -> Int -> IO (Either Error Milestone)-milestone user reqRepoName reqMilestoneNumber =-  githubGet ["repos", user, reqRepoName, "milestones", show reqMilestoneNumber]
− Github/Organizations.hs
@@ -1,35 +0,0 @@--- | The orgs API as described on <http://developer.github.com/v3/orgs/>.-module Github.Organizations (- publicOrganizationsFor-,publicOrganizationsFor'-,publicOrganization-,publicOrganization'-,module Github.Data-) where--import Github.Data-import Github.Private---- | The public organizations for a user, given the user's login, with authorization------ > publicOrganizationsFor' (Just ("github-username", "github-password")) "mike-burns"-publicOrganizationsFor' :: Maybe GithubAuth -> String -> IO (Either Error [SimpleOrganization])-publicOrganizationsFor' auth userName = githubGet' auth ["users", userName, "orgs"]---- | The public organizations for a user, given the user's login.------ > publicOrganizationsFor "mike-burns"-publicOrganizationsFor :: String -> IO (Either Error [SimpleOrganization])-publicOrganizationsFor = publicOrganizationsFor' Nothing---- | Details on a public organization. Takes the organization's login.------ > publicOrganization' (Just ("github-username", "github-password")) "thoughtbot"-publicOrganization' :: Maybe GithubAuth -> String -> IO (Either Error Organization)-publicOrganization' auth reqOrganizationName = githubGet' auth ["orgs", reqOrganizationName]---- | Details on a public organization. Takes the organization's login.------ > publicOrganization "thoughtbot"-publicOrganization :: String -> IO (Either Error Organization)-publicOrganization = publicOrganization' Nothing
− Github/Organizations/Members.hs
@@ -1,15 +0,0 @@--- | The organization members API as described on--- <http://developer.github.com/v3/orgs/members/>.-module Github.Organizations.Members (- membersOf-,module Github.Data-) where--import Github.Data-import Github.Private---- | All the users who are members of the specified organization.------ > membersOf "thoughtbot"-membersOf :: String -> IO (Either Error [GithubOwner])-membersOf organization = githubGet ["orgs", organization, "members"]
− Github/Private.hs
@@ -1,192 +0,0 @@-{-# LANGUAGE OverloadedStrings, StandaloneDeriving, DeriveDataTypeable #-}-{-# LANGUAGE CPP, FlexibleContexts #-}-module Github.Private where--import Github.Data-import Data.Aeson-import Data.Attoparsec.ByteString.Lazy-import Data.Data-import Data.Monoid-import Control.Applicative-import Data.List-import Data.CaseInsensitive (mk)-import qualified Data.ByteString.Char8 as BS-import qualified Data.ByteString.Lazy.Char8 as LBS-import Network.HTTP.Types (Status(..), notFound404)-import Network.HTTP.Conduit--- import Data.Conduit (ResourceT)-import qualified Control.Exception as E-import Data.Maybe (fromMaybe)---- | user/password for HTTP basic access authentication-data GithubAuth = GithubBasicAuth BS.ByteString BS.ByteString-                | GithubOAuth String-                deriving (Show, Data, Typeable, Eq, Ord)--githubGet :: (FromJSON b, Show b) => [String] -> IO (Either Error b)-githubGet = githubGet' Nothing--githubGet' :: (FromJSON b, Show b) => Maybe GithubAuth -> [String] -> IO (Either Error b)-githubGet' auth paths =-  githubAPI (BS.pack "GET")-            (buildUrl paths)-            auth-            (Nothing :: Maybe Value)--githubGetWithQueryString :: (FromJSON b, Show b) => [String] -> String -> IO (Either Error b)-githubGetWithQueryString = githubGetWithQueryString' Nothing--githubGetWithQueryString' :: (FromJSON b, Show b) => Maybe GithubAuth -> [String] -> String -> IO (Either Error b)-githubGetWithQueryString' auth paths qs =-  githubAPI (BS.pack "GET")-            (buildUrl paths ++ "?" ++ qs)-            auth-            (Nothing :: Maybe Value)--githubPost :: (ToJSON a, Show a, FromJSON b, Show b) => GithubAuth -> [String] -> a -> IO (Either Error b)-githubPost auth paths body =-  githubAPI (BS.pack "POST")-            (buildUrl paths)-            (Just auth)-            (Just body)--githubPatch :: (ToJSON a, Show a, FromJSON b, Show b) => GithubAuth -> [String] -> a -> IO (Either Error b)-githubPatch auth paths body =-  githubAPI (BS.pack "PATCH")-            (buildUrl paths)-            (Just auth)-            (Just body)--buildUrl :: [String] -> String-buildUrl paths = "https://api.github.com/" ++ intercalate "/" paths--githubAPI :: (ToJSON a, Show a, FromJSON b, Show b) => BS.ByteString -> String-          -> Maybe GithubAuth -> Maybe a -> IO (Either Error b)-githubAPI apimethod url auth body = do-  result <- doHttps apimethod url auth (encodeBody body)-  case result of-      Left e     -> return (Left (HTTPConnectionError e))-      Right resp -> either Left (\x -> jsonResultToE (LBS.pack (show x))-                                                   (fromJSON x))-                          <$> handleBody resp--  where-    encodeBody = Just . RequestBodyLBS . encode . toJSON--    handleBody resp = either (return . Left) (handleJson resp)-                             (parseJsonRaw (responseBody resp))--    -- This is an "escaping" version of "for", which returns (Right esc) if-    -- the value 'v' is Nothing; otherwise, it extracts the value from the-    -- Maybe, applies f, and return an IO (Either Error b).-    forE :: b -> Maybe a -> (a -> IO (Either Error b))-         -> IO (Either Error b)-    forE = flip . maybe . return . Right--    handleJson resp gotjson@(Array ary) =-        -- Determine whether the output was paginated, and if so, we must-        -- recurse to obtain the subsequent pages, and append those result-        -- bodies to the current one.  The aggregate will then be parsed.-        forE gotjson (lookup "Link" (responseHeaders resp)) $ \l ->-            forE gotjson (getNextUrl (BS.unpack l)) $ \nu ->-                either (return . Left . HTTPConnectionError)-                       (\nextResp -> do-                             nextJson <- handleBody nextResp-                             return $ (\(Array x) -> Array (ary <> x))-                                          <$> nextJson)-                       =<< doHttps apimethod nu auth Nothing-    handleJson _ gotjson = return (Right gotjson)--    getNextUrl l =-        if "rel=\"next\"" `isInfixOf` l-        then let s  = l-                 s' = Data.List.tail $ Data.List.dropWhile (/= '<') s-             in Just (Data.List.takeWhile (/= '>') s')-        else Nothing--doHttps :: BS.ByteString-           -> [Char]-           -> Maybe GithubAuth-           -> Maybe RequestBody-           -> IO (Either E.SomeException (Response LBS.ByteString))    -doHttps reqMethod url auth body = do-  let reqBody = fromMaybe (RequestBodyBS $ BS.pack "") body-      reqHeaders = maybe [] getOAuth auth-      Just uri = parseUrl url-      request = uri { method = reqMethod-                    , secure = True-                    , port = 443-                    , requestBody = reqBody-                    , responseTimeout = Just 20000000-                    , requestHeaders = reqHeaders <>-                                       [("User-Agent", "github.hs/0.7.4")]-                                       <> [("Accept", "application/vnd.github.preview")]-                    , checkStatus = successOrMissing-                    }-      authRequest = getAuthRequest auth request--  (getResponse authRequest >>= return . Right) `E.catches` [-      -- Re-throw AsyncException, otherwise execution will not terminate on-      -- SIGINT (ctrl-c).  All AsyncExceptions are re-thrown (not just-      -- UserInterrupt) because all of them indicate severe conditions and-      -- should not occur during normal operation.-      E.Handler (\e -> E.throw (e :: E.AsyncException)),-      E.Handler (\e -> (return . Left) (e :: E.SomeException))-      ]-  where-    getAuthRequest (Just (GithubBasicAuth user pass)) = applyBasicAuth user pass-    getAuthRequest _ = id-    getOAuth (GithubOAuth token) = [(mk (BS.pack "Authorization"),-                                     BS.pack ("token " ++ token))]-    getOAuth _ = []-    getResponse request = withManager $ \manager -> httpLbs request manager-#if MIN_VERSION_http_conduit(1, 9, 0)-    successOrMissing s@(Status sci _) hs cookiejar-#else-    successOrMissing s@(Status sci _) hs-#endif-      | (200 <= sci && sci < 300) || sci == 404 = Nothing-#if MIN_VERSION_http_conduit(1, 9, 0)-      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar-#else-      | otherwise = Just $ E.toException $ StatusCodeException s hs-#endif--doHttpsStatus :: BS.ByteString -> String -> GithubAuth -> Maybe RequestBody -> IO (Either Error Status)-doHttpsStatus reqMethod url auth payload = do-  result <- doHttps reqMethod url (Just auth) payload-  case result of-    Left e -> return (Left (HTTPConnectionError e))-    Right resp ->-      let status = responseStatus resp-          headers = responseHeaders resp-      in if status == notFound404-            -- doHttps silently absorbs 404 errors, but for this operation-            -- we want the user to know if they've tried to delete a-            -- non-existent repository-         then return (Left (HTTPConnectionError-                            (E.toException-                             (StatusCodeException status headers-#if MIN_VERSION_http_conduit(1, 9, 0)-                                 (responseCookieJar resp)-#endif-                                 ))))-             else return (Right status)--parseJsonRaw :: LBS.ByteString -> Either Error Value-parseJsonRaw jsonString =-  let parsed = parse json jsonString in-  case parsed of-       Data.Attoparsec.ByteString.Lazy.Done _ jsonResult -> Right jsonResult-       (Fail _ _ e) -> Left $ ParseError e--jsonResultToE :: Show b => LBS.ByteString -> Data.Aeson.Result b-              -> Either Error b-jsonResultToE jsonString result = case result of-    Success s -> Right s-    Error e   -> Left $ JsonError $-                 e ++ " on the JSON: " ++ LBS.unpack jsonString--parseJson :: (FromJSON b, Show b) => LBS.ByteString -> Either Error b-parseJson jsonString = either Left (jsonResultToE jsonString . fromJSON)-                              (parseJsonRaw jsonString)
− Github/PullRequests.hs
@@ -1,114 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--- | The pull requests API as documented at--- <http://developer.github.com/v3/pulls/>.-module Github.PullRequests (- pullRequestsFor'-,pullRequest'-,pullRequestCommits'-,pullRequestFiles'-,pullRequestsFor-,pullRequest-,pullRequestCommits-,pullRequestFiles-,isPullRequestMerged-,mergePullRequest-,createPullRequest-,updatePullRequest-,module Github.Data-) where--import Github.Data-import Github.Private-import Network.HTTP.Types-import qualified Data.Map as M-import Network.HTTP.Conduit (RequestBody(RequestBodyLBS))-import Data.Aeson---- | All pull requests for the repo, by owner and repo name.--- | With authentification------ > pullRequestsFor' (Just ("github-username", "github-password")) "rails" "rails"-pullRequestsFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [PullRequest])-pullRequestsFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "pulls"]---- | All pull requests for the repo, by owner and repo name.------ > pullRequestsFor "rails" "rails"-pullRequestsFor :: String -> String -> IO (Either Error [PullRequest])-pullRequestsFor = pullRequestsFor' Nothing---- | 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 GithubAuth -> String -> String -> Int -> IO (Either Error DetailedPullRequest)-pullRequest' auth userName reqRepoName number =-  githubGet' auth ["repos", userName, reqRepoName, "pulls", show number]---- | 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 :: String -> String -> Int -> IO (Either Error DetailedPullRequest)-pullRequest = pullRequest' Nothing---- | 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 GithubAuth -> String -> String -> Int -> IO (Either Error [Commit])-pullRequestCommits' auth userName reqRepoName number =-  githubGet' auth ["repos", userName, reqRepoName, "pulls", show number, "commits"]---- | All the commits on a pull request, given the repo owner, repo name, and--- the number of the pull request.------ > pullRequestCommits "thoughtbot" "paperclip" 688-pullRequestCommits :: String -> String -> Int -> IO (Either Error [Commit])-pullRequestCommits = pullRequestCommits' Nothing---- | 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 GithubAuth -> String -> String -> Int -> IO (Either Error [File])-pullRequestFiles' auth userName reqRepoName number =-  githubGet' auth ["repos", userName, reqRepoName, "pulls", show number, "files"]--- | 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 :: String -> String -> Int -> IO (Either Error [File])-pullRequestFiles = pullRequestFiles' Nothing---- | Check if pull request has been merged-isPullRequestMerged :: GithubAuth -> String -> String -> Int -> IO(Either Error Status)-isPullRequestMerged auth reqRepoOwner reqRepoName reqPullRequestNumber =-  doHttpsStatus "GET" (buildUrl ["repos", reqRepoOwner, reqRepoName, "pulls", (show reqPullRequestNumber), "merge"]) auth Nothing---- | Merge a pull request-mergePullRequest :: GithubAuth -> String -> String -> Int -> Maybe String -> IO(Either Error Status)-mergePullRequest auth reqRepoOwner reqRepoName reqPullRequestNumber commitMessage =-  doHttpsStatus "PUT" (buildUrl ["repos", reqRepoOwner, reqRepoName, "pulls", (show reqPullRequestNumber), "merge"]) auth (Just . RequestBodyLBS . encode . toJSON $ (buildCommitMessageMap commitMessage))---- | Update a pull request-updatePullRequest :: GithubAuth -> String -> String -> Int -> EditPullRequest -> IO (Either Error DetailedPullRequest)-updatePullRequest auth reqRepoOwner reqRepoName reqPullRequestNumber editPullRequest =-  githubPatch auth ["repos", reqRepoOwner, reqRepoName, "pulls", show reqPullRequestNumber] editPullRequest---buildCommitMessageMap :: Maybe String -> M.Map String String-buildCommitMessageMap (Just commitMessage) = M.singleton "commit_message" commitMessage-buildCommitMessageMap _ = M.empty--createPullRequest :: GithubAuth-                  -> String-                  -> String-                  -> CreatePullRequest-                  -> IO (Either Error DetailedPullRequest)-createPullRequest auth reqUserName reqRepoName createPR =-    githubPost auth ["repos", reqUserName, reqRepoName, "pulls"] createPR
− Github/Repos.hs
@@ -1,342 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-}--- | The Github Repos API, as documented at--- <http://developer.github.com/v3/repos/>-module Github.Repos (---- * Querying repositories- userRepos-,userRepos'-,userRepo-,userRepo'-,organizationRepos-,organizationRepos'-,organizationRepo-,organizationRepo'-,contributors-,contributors'-,contributorsWithAnonymous-,contributorsWithAnonymous'-,languagesFor-,languagesFor'-,tagsFor-,tagsFor'-,branchesFor-,branchesFor'-,contentsFor-,contentsFor'-,module Github.Data-,RepoPublicity(..)---- ** Create-,createRepo-,createOrganizationRepo-,newRepo-,NewRepo(..)---- ** Edit-,editRepo-,def-,Edit(..)---- ** Delete-,deleteRepo-) where--import Data.Default-import Data.Aeson.Types-import Github.Data-import Github.Private-import Network.HTTP.Conduit-import Control.Applicative-import qualified Control.Exception as E-import Network.HTTP.Types---- | Filter the list of the user's repos using any of these constructors.-data RepoPublicity =-    All     -- ^ All repos accessible to the user.-  | Owner   -- ^ Only repos owned by the user.-  | Public  -- ^ Only public repos.-  | Private -- ^ Only private repos.-  | Member  -- ^ Only repos to which the user is a member but not an owner.- deriving (Show, Eq)---- | The repos for a user, by their login. Can be restricted to just repos they--- own, are a member of, or publicize. Private repos are currently not--- supported.------ > userRepos "mike-burns" All-userRepos :: String -> RepoPublicity -> IO (Either Error [Repo])-userRepos = userRepos' Nothing---- | The repos for a user, by their login.--- With authentication, but note that private repos are currently not supported.------ > userRepos' (Just (GithubBasicAuth (user, password))) "mike-burns" All-userRepos' :: Maybe GithubAuth -> String -> RepoPublicity -> IO (Either Error [Repo])-userRepos' auth userName All =-  githubGetWithQueryString' auth ["users", userName, "repos"] "type=all"-userRepos' auth userName Owner =-  githubGetWithQueryString' auth ["users", userName, "repos"] "type=owner"-userRepos' auth userName Member =-  githubGetWithQueryString' auth ["users", userName, "repos"] "type=member"-userRepos' auth userName Public =-  githubGetWithQueryString' auth ["users", userName, "repos"] "type=public"-userRepos' _auth _userName Private =-  return $ Left $ UserError "Cannot access private repos using userRepos"---- | The repos for an organization, by the organization name.------ > organizationRepos "thoughtbot"-organizationRepos :: String -> IO (Either Error [Repo])-organizationRepos = organizationRepos' Nothing---- | The repos for an organization, by the organization name.--- With authentication.------ > organizationRepos (Just (GithubBasicAuth (user, password))) "thoughtbot"-organizationRepos' :: Maybe GithubAuth -> String -> IO (Either Error [Repo])-organizationRepos' auth orgName = githubGet' auth ["orgs", orgName, "repos"]---- | A specific organization repo, by the organization name.------ > organizationRepo "thoughtbot" "github"-organizationRepo :: String -> String -> IO (Either Error Repo)-organizationRepo = organizationRepo' Nothing---- | A specific organization repo, by the organization name.--- With authentication.------ > organizationRepo (Just (GithubBasicAuth (user, password))) "thoughtbot" "github"-organizationRepo' :: Maybe GithubAuth -> String -> String -> IO (Either Error Repo)-organizationRepo' auth orgName reqRepoName = githubGet' auth ["orgs", orgName, reqRepoName]---- | Details on a specific repo, given the owner and repo name.------ > userRepo "mike-burns" "github"-userRepo :: String -> String -> IO (Either Error Repo)-userRepo = userRepo' Nothing---- | Details on a specific repo, given the owner and repo name.--- With authentication.------ > userRepo' (Just (GithubBasicAuth (user, password))) "mike-burns" "github"-userRepo' :: Maybe GithubAuth -> String -> String -> IO (Either Error Repo)-userRepo' auth userName reqRepoName = githubGet' auth ["repos", userName, reqRepoName]---- | The contributors to a repo, given the owner and repo name.------ > contributors "thoughtbot" "paperclip"-contributors :: String -> String -> IO (Either Error [Contributor])-contributors = contributors' Nothing---- | The contributors to a repo, given the owner and repo name.--- With authentication.------ > contributors' (Just (GithubBasicAuth (user, password))) "thoughtbot" "paperclip"-contributors' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Contributor])-contributors' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "contributors"]---- | 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 :: String -> String -> IO (Either Error [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 (GithubBasicAuth (user, password))) "thoughtbot" "paperclip"-contributorsWithAnonymous' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Contributor])-contributorsWithAnonymous' auth userName reqRepoName =-  githubGetWithQueryString' auth-    ["repos", userName, reqRepoName, "contributors"]-    "anon=true"----- | 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 :: String -> String -> IO (Either Error [Language])-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 (GithubBasicAuth (user, password))) "mike-burns" "ohlaunch"-languagesFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Language])-languagesFor' auth userName reqRepoName = do-  result <- githubGet' auth ["repos", userName, reqRepoName, "languages"]-  return $ either Left (Right . getLanguages) result---- | The git tags on a repo, given the repo owner and name.------ > tagsFor "thoughtbot" "paperclip"-tagsFor :: String -> String -> IO (Either Error [Tag])-tagsFor = tagsFor' Nothing---- | The git tags on a repo, given the repo owner and name.--- With authentication.------ > tagsFor' (Just (GithubBasicAuth (user, password))) "thoughtbot" "paperclip"-tagsFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Tag])-tagsFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "tags"]---- | The git branches on a repo, given the repo owner and name.------ > branchesFor "thoughtbot" "paperclip"-branchesFor :: String -> String -> IO (Either Error [Branch])-branchesFor = branchesFor' Nothing---- | The git branches on a repo, given the repo owner and name.--- With authentication.------ > branchesFor' (Just (GithubBasicAuth (user, password))) "thoughtbot" "paperclip"-branchesFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Branch])-branchesFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "branches"]---- | 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 :: String -> String -> String -> Maybe String -> 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 (GithubBasicAuth (user, password))) "thoughtbot" "paperclip" "README.md"-contentsFor' :: Maybe GithubAuth ->  String -> String -> String -> Maybe String -> IO (Either Error Content)-contentsFor' auth userName reqRepoName reqContentPath ref =-  githubGetWithQueryString' auth-  ["repos", userName, reqRepoName, "contents", reqContentPath] $-  maybe "" ("ref="++) ref---data NewRepo = NewRepo {-  newRepoName         :: String-, newRepoDescription  :: (Maybe String)-, newRepoHomepage     :: (Maybe String)-, newRepoPrivate      :: (Maybe Bool)-, newRepoHasIssues    :: (Maybe Bool)-, newRepoHasWiki      :: (Maybe Bool)-, newRepoAutoInit     :: (Maybe Bool)-} deriving Show--instance ToJSON  NewRepo where-  toJSON (NewRepo { newRepoName         = name-                  , newRepoDescription  = description-                  , newRepoHomepage     = homepage-                  , newRepoPrivate      = private-                  , newRepoHasIssues    = hasIssues-                  , newRepoHasWiki      = hasWiki-                  , newRepoAutoInit     = autoInit-                  }) = object-                  [ "name"                .= name-                  , "description"         .= description-                  , "homepage"            .= homepage-                  , "private"             .= private-                  , "has_issues"          .= hasIssues-                  , "has_wiki"            .= hasWiki-                  , "auto_init"           .= autoInit-                  ]--newRepo :: String -> NewRepo-newRepo name = NewRepo name Nothing Nothing Nothing Nothing Nothing Nothing---- |--- Create a new repository.------ > createRepo (GithubBasicAuth (user, password)) (newRepo "some_repo") {newRepoHasIssues = Just False}-createRepo :: GithubAuth -> NewRepo -> IO (Either Error Repo)-createRepo auth = githubPost auth ["user", "repos"]---- |--- Create a new repository for an organization.------ > createOrganizationRepo (GithubBasicAuth (user, password)) "thoughtbot" (newRepo "some_repo") {newRepoHasIssues = Just False}-createOrganizationRepo :: GithubAuth -> String -> NewRepo -> IO (Either Error Repo)-createOrganizationRepo auth org = githubPost auth ["orgs", org, "repos"]--data Edit = Edit {-  editName         :: Maybe String-, editDescription  :: Maybe String-, editHomepage     :: Maybe String-, editPublic       :: Maybe Bool-, editHasIssues    :: Maybe Bool-, editHasWiki      :: Maybe Bool-, editHasDownloads :: Maybe Bool-} deriving Show--instance Default Edit where-  def = Edit def def def def def def def--instance ToJSON  Edit where-  toJSON (Edit { editName         = name-               , editDescription  = description-               , editHomepage     = homepage-               , editPublic       = public-               , editHasIssues    = hasIssues-               , editHasWiki      = hasWiki-               , editHasDownloads = hasDownloads-               }) = object-               [ "name"          .= name-               , "description"   .= description-               , "homepage"      .= homepage-               , "public"        .= public-               , "has_issues"    .= hasIssues-               , "has_wiki"      .= hasWiki-               , "has_downloads" .= hasDownloads-               ]---- |--- Edit an existing repository.------ > editRepo (GithubBasicAuth (user, password)) "some_user" "some_repo" def {editDescription = Just "some description"}-editRepo :: GithubAuth-     -> String      -- ^ owner-     -> String      -- ^ repository name-     -> Edit-     -> IO (Either Error Repo)-editRepo auth user repo body = githubPatch auth ["repos", user, repo] b-  where-    -- if no name is given, use curent name-    b = body {editName = editName body <|> Just repo}---- |--- Delete an existing repository.------ > deleteRepo (GithubBasicAuth (user, password)) "thoughtbot" "some_repo"-deleteRepo :: GithubAuth-           -> String      -- ^ owner-           -> String      -- ^ repository name-           -> IO (Either Error ())-deleteRepo auth owner repo = do-  result <- doHttps "DELETE" url (Just auth) Nothing-  case result of-      Left e -> return (Left (HTTPConnectionError e))-      Right resp ->-          let status = responseStatus resp-              headers = responseHeaders resp-          in if status == notFound404-                -- doHttps silently absorbs 404 errors, but for this operation-                -- we want the user to know if they've tried to delete a-                -- non-existent repository-             then return (Left (HTTPConnectionError-                                (E.toException-                                 (StatusCodeException status headers-#if MIN_VERSION_http_conduit(1, 9, 0)-                                 (responseCookieJar resp)-#endif-                                 ))))-             else return (Right ())-  where-    url = "https://api.github.com/repos/" ++ owner ++ "/" ++ repo
− Github/Repos/Collaborators.hs
@@ -1,36 +0,0 @@--- | The repo collaborators API as described on--- <http://developer.github.com/v3/repos/collaborators/>.-module Github.Repos.Collaborators (- collaboratorsOn-,isCollaboratorOn-,module Github.Data-) where--import Github.Data-import Github.Private--import Data.ByteString.Char8 (pack)-import qualified Network.HTTP.Conduit as C (responseStatus)-import qualified Network.HTTP.Types as T (statusCode)---- | All the users who have collaborated on a repo.------ > collaboratorsOn "thoughtbot" "paperclip"-collaboratorsOn :: String -> String -> IO (Either Error [GithubOwner])-collaboratorsOn userName reqRepoName =-  githubGet ["repos", userName, reqRepoName, "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 "mike-burns" "thoughtbot" "paperclip"--- > isCollaboratorOn "johnson" "thoughtbot" "paperclip"-isCollaboratorOn :: String -> String -> String -> IO (Either Error Bool)-isCollaboratorOn userName repoOwnerName reqRepoName = do-   result <- doHttps (pack "GET")-                     (buildUrl ["repos", repoOwnerName, reqRepoName, "collaborators", userName])-                     Nothing-                     Nothing-   return $ either (Left . HTTPConnectionError)-                   (Right . (204 ==) . T.statusCode . C.responseStatus)-                   result
− Github/Repos/Commits.hs
@@ -1,53 +0,0 @@--- | The repo commits API as described on--- <http://developer.github.com/v3/repos/commits/>.-module Github.Repos.Commits (- commitsFor-,commit-,commentsFor-,commitCommentsFor-,commitCommentFor-,diff-,module Github.Data-) where--import Github.Data-import Github.Private---- | The commit history for a repo.------ > commitsFor "mike-burns" "github"-commitsFor :: String -> String -> IO (Either Error [Commit])-commitsFor user repo = githubGet ["repos", user, repo, "commits"]---- | Details on a specific SHA1 for a repo.------ > commit "mike-burns" "github" "9d1a9a361266c3c890b1108ad2fdf52f824b1b81"-commit :: String -> String -> String -> IO (Either Error Commit)-commit user repo sha1 = githubGet ["repos", user, repo, "commits", sha1]---- | All the comments on a Github repo.------ > commentsFor "thoughtbot" "paperclip"-commentsFor :: String -> String -> IO (Either Error [Comment])-commentsFor user repo = githubGet ["repos", user, repo, "comments"]---- | Just the comments on a specific SHA for a given Github repo.------ > commitCommentsFor "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-commitCommentsFor :: String -> String -> String -> IO (Either Error [Comment])-commitCommentsFor user repo sha1 =-  githubGet ["repos", user, repo, "commits", sha1, "comments"]---- | A comment, by its ID, relative to the Github repo.------ > commitCommentFor "thoughtbot" "paperclip" "669575"-commitCommentFor :: String -> String -> String -> IO (Either Error Comment)-commitCommentFor user repo reqCommentId =-  githubGet ["repos", user, repo, "comments", reqCommentId]---- | The diff between two treeishes on a repo.------ > diff "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b" "HEAD"-diff :: String -> String -> String -> String -> IO (Either Error Diff)-diff user repo base headref =-  githubGet ["repos", user, repo, "compare", base ++ "..." ++ headref]
− Github/Repos/Forks.hs
@@ -1,24 +0,0 @@--- | Hot forking action, as described at--- <http://developer.github.com/v3/repos/forks/>.-module Github.Repos.Forks (- forksFor-,forksFor'-,module Github.Data-) where--import Github.Data-import Github.Private---- | All the repos that are forked off the given repo.------ > forksFor "thoughtbot" "paperclip"-forksFor :: String -> String -> IO (Either Error [Repo])-forksFor = forksFor' Nothing---- | All the repos that are forked off the given repo.--- | With authentication------ > forksFor' (Just (GithubUser (user, password))) "thoughtbot" "paperclip"-forksFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [Repo])-forksFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "forks"]
− Github/Repos/Starring.hs
@@ -1,28 +0,0 @@--- | The repo starring API as described on--- <http://developer.github.com/v3/repos/starring/>.-module Github.Repos.Starring (- stargazersFor-,reposStarredBy-,myStarred-,module Github.Data-) where--import Github.Data-import Github.Private---- | The list of users that have starred the specified Github repo.------ > userInfoFor' Nothing "mike-burns"-stargazersFor :: Maybe GithubAuth -> String -> String -> IO (Either Error [GithubOwner])-stargazersFor auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "stargazers"]---- | All the public repos starred by the specified user.------ > reposStarredBy Nothing "croaky"-reposStarredBy :: Maybe GithubAuth -> String -> IO (Either Error [Repo])-reposStarredBy auth userName = githubGet' auth ["users", userName, "starred"]---- | All the repos starred by the authenticated user.-myStarred :: GithubAuth -> IO (Either Error [Repo])-myStarred auth = githubGet' (Just auth) ["user", "starred"]
− Github/Repos/Subscribing.hs
@@ -1,39 +0,0 @@--- | The repo subscribing API as described on--- <http://developer.github.com/v3/repos/watching/>.-module Github.Repos.Subscribing (- subscribersFor-,subscribersFor'-,reposSubscribedToBy-,reposSubscribedToBy'-,module Github.Data-) where--import Github.Data-import Github.Private---- | The list of users that are subscribed to the specified Github repo.------ > subscribersFor "thoughtbot" "paperclip"-subscribersFor :: String -> String -> IO (Either Error [GithubOwner])-subscribersFor = subscribersFor' Nothing---- | The list of users that are subscribed to the specified Github repo.--- | With authentication------ > subscribersFor' (Just (GithubUser (user, password))) "thoughtbot" "paperclip"-subscribersFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [GithubOwner])-subscribersFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "subscribers"]---- | All the public repos subscribed to by the specified user.------ > reposSubscribedToBy "croaky"-reposSubscribedToBy :: String -> IO (Either Error [Repo])-reposSubscribedToBy = reposSubscribedToBy' Nothing---- | All the public repos subscribed to by the specified user.--- | With authentication------ > reposSubscribedToBy' (Just (GithubUser (user, password))) "croaky"-reposSubscribedToBy' :: Maybe GithubAuth -> String -> IO (Either Error [Repo])-reposSubscribedToBy' auth userName = githubGet' auth ["users", userName, "subscriptions"]
− Github/Repos/Watching.hs
@@ -1,39 +0,0 @@--- | The repo watching API as described on--- <http://developer.github.com/v3/repos/watching/>.-module Github.Repos.Watching (- watchersFor-,watchersFor'-,reposWatchedBy-,reposWatchedBy'-,module Github.Data-) where--import Github.Data-import Github.Private---- | The list of users that are watching the specified Github repo.------ > watchersFor "thoughtbot" "paperclip"-watchersFor :: String -> String -> IO (Either Error [GithubOwner])-watchersFor = watchersFor' Nothing---- | The list of users that are watching the specified Github repo.--- | With authentication------ > watchersFor' (Just (GithubUser (user, password))) "thoughtbot" "paperclip"-watchersFor' :: Maybe GithubAuth -> String -> String -> IO (Either Error [GithubOwner])-watchersFor' auth userName reqRepoName =-  githubGet' auth ["repos", userName, reqRepoName, "watchers"]---- | All the public repos watched by the specified user.------ > reposWatchedBy "croaky"-reposWatchedBy :: String -> IO (Either Error [Repo])-reposWatchedBy = reposWatchedBy' Nothing---- | All the public repos watched by the specified user.--- | With authentication------ > reposWatchedBy' (Just (GithubUser (user, password))) "croaky"-reposWatchedBy' :: Maybe GithubAuth -> String -> IO (Either Error [Repo])-reposWatchedBy' auth userName = githubGet' auth ["users", userName, "watched"]
− Github/Repos/Webhooks.hs
@@ -1,116 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP #-}--- | The webhooks API, as described at--- <https://developer.github.com/v3/repos/hooks/>--- <https://developer.github.com/webhooks>--module Github.Repos.Webhooks (---- * Querying repositories-  webhooksFor'- ,webhookFor'---- ** Create- ,createRepoWebhook'---- ** Edit  - ,editRepoWebhook'---- ** Test  - ,testPushRepoWebhook'- ,pingRepoWebhook'---- ** Delete  - ,deleteRepoWebhook'- ,NewRepoWebhook(..)- ,EditRepoWebhook(..)- ,RepoOwner- ,RepoName- ,RepoWebhookId-) where--import Github.Data-import Github.Private-import qualified Data.Map as M-import Network.HTTP.Conduit-import Network.HTTP.Types-import Data.Aeson--type RepoOwner = String-type RepoName = String-type RepoWebhookId = Int-    -data NewRepoWebhook = NewRepoWebhook {-  newRepoWebhookName :: String- ,newRepoWebhookConfig :: M.Map String String- ,newRepoWebhookEvents :: Maybe [RepoWebhookEvent]- ,newRepoWebhookActive :: Maybe Bool-} deriving Show--data EditRepoWebhook = EditRepoWebhook {-  editRepoWebhookConfig :: Maybe (M.Map String String)- ,editRepoWebhookEvents :: Maybe [RepoWebhookEvent]- ,editRepoWebhookAddEvents :: Maybe [RepoWebhookEvent]- ,editRepoWebhookRemoveEvents :: Maybe [RepoWebhookEvent]- ,editRepoWebhookActive :: Maybe Bool-} deriving Show-                  -instance ToJSON NewRepoWebhook where-  toJSON (NewRepoWebhook { newRepoWebhookName = name-                         , newRepoWebhookConfig = config-                         , newRepoWebhookEvents = events-                         , newRepoWebhookActive = active--             }) = object-             [ "name" .= name-             , "config" .= config-             , "events" .= events-             , "active" .= active-             ]--instance ToJSON EditRepoWebhook where             -  toJSON (EditRepoWebhook { editRepoWebhookConfig = config-                          , editRepoWebhookEvents = events-                          , editRepoWebhookAddEvents = addEvents-                          , editRepoWebhookRemoveEvents = removeEvents-                          , editRepoWebhookActive = active-             }) = object-             [ "config" .= config-             , "events" .= events-             , "add_events" .= addEvents-             , "remove_events" .= removeEvents-             , "active" .= active-             ]-             -webhooksFor' :: GithubAuth -> RepoOwner -> RepoName -> IO (Either Error [RepoWebhook])-webhooksFor' auth owner reqRepoName =-  githubGet' (Just auth) ["repos", owner, reqRepoName, "hooks"]--webhookFor' :: GithubAuth -> RepoOwner -> RepoName -> RepoWebhookId -> IO (Either Error RepoWebhook)-webhookFor' auth owner reqRepoName webhookId =-  githubGet' (Just auth) ["repos", owner, reqRepoName, "hooks", (show webhookId)]--createRepoWebhook' :: GithubAuth -> RepoOwner -> RepoName -> NewRepoWebhook -> IO (Either Error RepoWebhook)-createRepoWebhook' auth owner reqRepoName = githubPost auth ["repos", owner, reqRepoName, "hooks"]--editRepoWebhook' :: GithubAuth -> RepoOwner -> RepoName -> RepoWebhookId -> EditRepoWebhook -> IO (Either Error RepoWebhook)-editRepoWebhook' auth owner reqRepoName webhookId edit = githubPatch auth ["repos", owner, reqRepoName, "hooks", (show webhookId)] edit-                                                            -testPushRepoWebhook' :: GithubAuth -> RepoOwner -> RepoName -> RepoWebhookId -> IO (Either Error Status)-testPushRepoWebhook' auth owner reqRepoName webhookId =-  doHttpsStatus "POST" (createWebhookOpUrl owner reqRepoName webhookId (Just "tests")) auth (Just . RequestBodyLBS . encode $ (decode "{}" :: Maybe (M.Map String Int))) --pingRepoWebhook' :: GithubAuth -> RepoOwner -> RepoName -> RepoWebhookId -> IO (Either Error Status)-pingRepoWebhook' auth owner reqRepoName webhookId =-  doHttpsStatus "POST" (createWebhookOpUrl owner reqRepoName webhookId (Just "pings")) auth Nothing--deleteRepoWebhook' :: GithubAuth -> RepoOwner -> RepoName -> RepoWebhookId -> IO (Either Error Status)-deleteRepoWebhook' auth owner reqRepoName webhookId =-  doHttpsStatus "DELETE" (createWebhookOpUrl owner reqRepoName webhookId Nothing) auth Nothing--createBaseWebhookUrl :: RepoOwner -> RepoName -> RepoWebhookId -> String-createBaseWebhookUrl owner reqRepoName webhookId = "https://api.github.com/repos/" ++ owner ++ "/" ++ reqRepoName ++ "/hooks/" ++ (show webhookId)--createWebhookOpUrl :: RepoOwner -> RepoName -> RepoWebhookId -> Maybe String -> String-createWebhookOpUrl owner reqRepoName webhookId Nothing = createBaseWebhookUrl owner reqRepoName webhookId-createWebhookOpUrl owner reqRepoName webhookId (Just operation) = createBaseWebhookUrl owner reqRepoName webhookId ++ "/" ++ operation
− Github/Repos/Webhooks/Validate.hs
@@ -1,35 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- | Verification of incomming webhook payloads, as described at--- <https://developer.github.com/webhooks/securing/>--module Github.Repos.Webhooks.Validate (-  isValidPayload-) where--import Control.Applicative-import Crypto.Hash-import qualified Data.ByteString.Char8 as BS-import Data.Byteable (constEqBytes, toBytes)-import qualified Data.ByteString.Base16 as Hex-import Data.Monoid----- | Validates a given payload against a given HMAC hexdigest using a given--- secret.--- Returns 'True' iff the given hash is non-empty and it's a valid signature of--- the payload.-isValidPayload-  :: String             -- ^ the secret-  -> Maybe String       -- ^ the hash provided by the remote party-                        -- in @X-Hub-Signature@ (if any),-                        -- including the 'sha1=...' prefix-  -> BS.ByteString      -- ^ the body-  -> Bool-isValidPayload secret shaOpt payload = maybe False (constEqBytes sign) shaOptBS-  where-    shaOptBS = BS.pack <$> shaOpt-    hexDigest = Hex.encode . toBytes . hmacGetDigest--    hm = hmac (BS.pack secret) payload :: HMAC SHA1-    sign = "sha1=" <> hexDigest hm
− Github/Search.hs
@@ -1,42 +0,0 @@--- | The Github Search API, as described at--- <http://developer.github.com/v3/search/>.-module Github.Search(- searchRepos'-,searchRepos-,searchCode'-,searchCode-,module Github.Data-) where--import Github.Data-import Github.Private---- | Perform a repository search.--- | With authentication.------ > searchRepos' (Just $ GithubBasicAuth "github-username" "github-password') "q=a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchRepos' :: Maybe GithubAuth -> String -> IO (Either Error SearchReposResult)-searchRepos' auth queryString = githubGetWithQueryString' auth ["search", "repositories"] queryString---- | Perform a repository search.--- | Without authentication.------ > searchRepos "q=a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchRepos :: String -> IO (Either Error SearchReposResult)-searchRepos = searchRepos' Nothing ---- | Perform a code search.--- | With authentication.------ > searchCode' (Just $ GithubBasicAuth "github-username" "github-password') "q=a in%3Aname language%3Ahaskell created%3A>2013-10-01&per_page=100"-searchCode' :: Maybe GithubAuth -> String -> IO (Either Error SearchCodeResult)-searchCode' auth queryString = githubGetWithQueryString' auth ["search", "code"] queryString---- | Perform a code search.--- | Without authentication.------ > searchCode "q=addClass+in:file+language:js+repo:jquery/jquery"-searchCode :: String -> IO (Either Error SearchCodeResult)-searchCode = searchCode' Nothing --
− Github/Users.hs
@@ -1,23 +0,0 @@--- | The Github Users API, as described at--- <http://developer.github.com/v3/users/>.-module Github.Users (- userInfoFor-,userInfoFor'-,module Github.Data-) where--import Github.Data-import Github.Private---- | The information for a single user, by login name.--- | With authentification------ > userInfoFor' (Just ("github-username", "github-password")) "mike-burns"-userInfoFor' :: Maybe GithubAuth -> String -> IO (Either Error DetailedOwner)-userInfoFor' auth userName = githubGet' auth ["users", userName]---- | The information for a single user, by login name.------ > userInfoFor "mike-burns"-userInfoFor :: String -> IO (Either Error DetailedOwner)-userInfoFor = userInfoFor' Nothing
− Github/Users/Followers.hs
@@ -1,22 +0,0 @@--- | The user followers API as described on--- <http://developer.github.com/v3/users/followers/>.-module Github.Users.Followers (- usersFollowing-,usersFollowedBy-,module Github.Data-) where--import Github.Data-import Github.Private---- | All the users following the given user.------ > usersFollowing "mike-burns"-usersFollowing :: String -> IO (Either Error [GithubOwner])-usersFollowing userName = githubGet ["users", userName, "followers"]---- | All the users that the given user follows.------ > usersFollowedBy "mike-burns"-usersFollowedBy :: String -> IO (Either Error [GithubOwner])-usersFollowedBy userName = githubGet ["users", userName, "following"]
README.md view
@@ -1,10 +1,15 @@-Github+GitHub ------ -The Github API v3 for Haskell.+[![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) -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+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 improving.  Installation@@ -12,55 +17,89 @@  In your project's cabal file: -    -- Packages needed in order to build this package.-    Build-depends:       github+```cabal+Build-depends:       github+```  Or from the command line: -    cabal install github+```sh+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.+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). -Each function has a sample written for it.+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. -All functions produce an `IO (Either Error a)`, where `a` is the actual thing+IO functions produce an `IO (Either Error a)`, where `a` is the actual thing you want. You must call the function using IO goodness, then dispatch on the possible error message. Here's an example from the samples: -    import qualified Github.Users.Followers as Github-    import Data.List (intercalate)+Many function have samples under+[`samples/`](https://github.com/haskell-github/github/tree/master/samples) directory. -    main = do-      possibleUsers <- Github.usersFollowing "mike-burns"-      putStrLn $ either (("Error: "++) . show)-                        (intercalate "\n" . map formatUser)+```hs+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}++import Prelude.Compat++import Data.Text         (Text, pack)+import Data.Text.IO as T (putStrLn)+import Data.Monoid       ((<>))++import GitHub (github')+import qualified GitHub++main :: IO ()+main = do+    possibleUsers <- github' GitHub.usersFollowingR "phadej"+    T.putStrLn $ either (("Error: " <>) . pack . show)+                        (foldMap ((<> "\n") . formatUser))                         possibleUsers -    formatUser = Github.githubOwnerLogin+formatUser :: GitHub.SimpleUser -> Text+formatUser = GitHub.untagName . GitHub.simpleUserLogin+```  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 ========= -Copyright 2011, 2012 Mike Burns.-Copyright 2013-2014 John Wiegley.+Copyright 2011-2012 Mike Burns.+Copyright 2013-2015 John Wiegley.+Copyright 2016-2019 Oleg Grenrus.  Available under the BSD 3-clause license.++[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/issue-search.json view
@@ -0,0 +1,98 @@+{+  "total_count": 2,+  "incomplete_results": false,+  "items": [+    {+      "url": "https://api.github.com/repos/phadej/github/issues/130",+      "labels_url": "https://api.github.com/repos/phadej/github/issues/130/labels{/name}",+      "comments_url": "https://api.github.com/repos/phadej/github/issues/130/comments",+      "events_url": "https://api.github.com/repos/phadej/github/issues/130/events",+      "html_url": "https://github.com/phadej/github/pull/130",+      "id": 123898390,+      "number": 130,+      "title": "Make test runner more robust",+      "user": {+        "login": "phadej",+        "id": 51087,+        "avatar_url": "https://avatars.githubusercontent.com/u/51087?v=3",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "labels": [++      ],+      "state": "closed",+      "locked": false,+      "assignee": null,+      "assignees": [],+      "milestone": null,+      "comments": 0,+      "created_at": "2015-12-25T21:37:39Z",+      "updated_at": "2015-12-26T08:57:52Z",+      "closed_at": "2015-12-25T23:32:12Z",+      "pull_request": {+        "url": "https://api.github.com/repos/phadej/github/pulls/130",+        "html_url": "https://github.com/phadej/github/pull/130",+        "diff_url": "https://github.com/phadej/github/pull/130.diff",+        "patch_url": "https://github.com/phadej/github/pull/130.patch"+      },+      "body": "As they use access token, it's highly unlikely it will be rate limited. ATM there's only one request per test job. i.e. travis could be re-enabled.\r\n\r\nExample run https://travis-ci.org/phadej/github/builds/98815089\r\nSome tests are pending as secret is made for this `jwiegley/github` repository.",+      "score": 0.75566536+    },+    {+      "url": "https://api.github.com/repos/phadej/github/issues/127",+      "labels_url": "https://api.github.com/repos/phadej/github/issues/127/labels{/name}",+      "comments_url": "https://api.github.com/repos/phadej/github/issues/127/comments",+      "events_url": "https://api.github.com/repos/phadej/github/issues/127/events",+      "html_url": "https://github.com/phadej/github/issues/127",+      "id": 119694665,+      "number": 127,+      "title": "Decouple request creation from execution",+      "user": {+        "login": "phadej",+        "id": 51087,+        "avatar_url": "https://avatars.githubusercontent.com/u/51087?v=3",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "labels": [++      ],+      "state": "open",+      "locked": false,+      "assignee": null,+      "assignees": [],+      "milestone": null,+      "comments": 2,+      "created_at": "2015-12-01T11:09:03Z",+      "updated_at": "2015-12-25T19:15:33Z",+      "closed_at": null,+      "body": "After working with this API, and making few others, I found that separating request creation and execution is better (i.e. more flexible) design.\r\n\r\nNow one cannot use different network client or add new endpoints.\r\n\r\nShorly\r\n\r\n```hs\r\n-- New stuff:\r\ndata GithubRequest a = GithubRequestGet Url\r\n                     | ...\r\n\r\n-- or alternatively\r\ndata GithubRequest a where\r\n  GithubRequestGet :: Url -> GithubRequest a\r\n  GithubRequestMultiGet :: Url -> GithubRequest [a]\r\n\r\nexecGithubRequest :: FromJSON a => GithubRequest a -> IO (Either Error a)\r\nexecGithubRequest' :: FromJSON a => Maybe GithubAuth -> GithubRequest a -> IO (Either Error a)\r\n\r\npublicOrganizationForRequest :: String -> GithubRequest [SimpleOrganisation]\r\npublicOrganizationForRequest org = GithubRequestGet ...\r\n\r\n-- Old IO methods become:\r\npublicOrganizationsFor :: String -> IO (Either Error [SimpleOrganization])\r\npublicOrganizationsFor = execGithubRequest . publicOrganizationForRequest\r\n\r\npublicOrganizationsFor' :: Maybe GithubAuth -> String -> IO (Either Error [SimpleOrganization])\r\npublicOrganizationsFor' auth = execGithubRequest' auth . publicOrganizationForRequest\r\n```\r\n\r\nHow does this sound? I can make a refactoring, it's quite straight-forward.",+      "score": 0.7265285+    }+  ]+}
+ fixtures/list-teams.json view
@@ -0,0 +1,13 @@+[+  {+    "id": 1,+    "url": "https://api.github.com/teams/1",+    "name": "Justice League",+    "slug": "justice-league",+    "description": "A great team.",+    "privacy": "closed",+    "permission": "admin",+    "members_url": "https://api.github.com/teams/1/members{/member}",+    "repositories_url": "https://api.github.com/teams/1/repos"+  }+]
+ fixtures/members-list.json view
@@ -0,0 +1,21 @@+[+  {+    "login": "octocat",+    "id": 1,+    "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+  }+]
+ 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-opened.json view
@@ -0,0 +1,311 @@+{+  "url": "https://api.github.com/repos/phadej/github/pulls/9",+  "id": 144079630,+  "html_url": "https://github.com/phadej/github/pull/9",+  "diff_url": "https://github.com/phadej/github/pull/9.diff",+  "patch_url": "https://github.com/phadej/github/pull/9.patch",+  "issue_url": "https://api.github.com/repos/phadej/github/issues/9",+  "number": 9,+  "state": "open",+  "locked": false,+  "title": "Fetch my pull requests",+  "user": {+    "login": "phadej",+    "id": 123898390,+    "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+    "gravatar_id": "",+    "url": "https://api.github.com/users/phadej",+    "html_url": "https://github.com/phadej",+    "followers_url": "https://api.github.com/users/phadej/followers",+    "following_url": "https://api.github.com/users/phadej/following{/other_user}",+    "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+    "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+    "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+    "organizations_url": "https://api.github.com/users/phadej/orgs",+    "repos_url": "https://api.github.com/users/phadej/repos",+    "events_url": "https://api.github.com/users/phadej/events{/privacy}",+    "received_events_url": "https://api.github.com/users/phadej/received_events",+    "type": "User",+    "site_admin": false+  },+  "body": "",+  "created_at": "2017-10-01T17:22:12Z",+  "updated_at": "2017-10-01T17:22:12Z",+  "closed_at": null,+  "merged_at": null,+  "merge_commit_sha": null,+  "assignee": null,+  "assignees": [+  ],+  "milestone": null,+  "commits_url": "https://api.github.com/repos/phadej/github/pulls/9/commits",+  "review_comments_url": "https://api.github.com/repos/phadej/github/pulls/9/comments",+  "review_comment_url": "https://api.github.com/repos/phadej/github/pulls/comments{/number}",+  "comments_url": "https://api.github.com/repos/phadej/github/issues/9/comments",+  "statuses_url": "https://api.github.com/repos/phadej/github/statuses/20218048bb9529de09f1fdaa9126f60ffeb07ce5",+  "head": {+    "label": "phadej:fetch-my-pull-requests",+    "ref": "fetch-my-pull-requests",+    "sha": "20218048bb9529de09f1fdaa9126f60ffeb07ce5",+    "user": {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    },+    "repo": {+      "id": 102602684,+      "name": "github",+      "full_name": "phadej/github",+      "owner": {+        "login": "phadej",+        "id": 123898390,+        "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "private": true,+      "html_url": "https://github.com/phadej/github",+      "description": null,+      "fork": false,+      "url": "https://api.github.com/repos/phadej/github",+      "forks_url": "https://api.github.com/repos/phadej/github/forks",+      "keys_url": "https://api.github.com/repos/phadej/github/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/phadej/github/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/phadej/github/teams",+      "hooks_url": "https://api.github.com/repos/phadej/github/hooks",+      "issue_events_url": "https://api.github.com/repos/phadej/github/issues/events{/number}",+      "events_url": "https://api.github.com/repos/phadej/github/events",+      "assignees_url": "https://api.github.com/repos/phadej/github/assignees{/user}",+      "branches_url": "https://api.github.com/repos/phadej/github/branches{/branch}",+      "tags_url": "https://api.github.com/repos/phadej/github/tags",+      "blobs_url": "https://api.github.com/repos/phadej/github/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/phadej/github/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/phadej/github/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/phadej/github/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/phadej/github/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/phadej/github/languages",+      "stargazers_url": "https://api.github.com/repos/phadej/github/stargazers",+      "contributors_url": "https://api.github.com/repos/phadej/github/contributors",+      "subscribers_url": "https://api.github.com/repos/phadej/github/subscribers",+      "subscription_url": "https://api.github.com/repos/phadej/github/subscription",+      "commits_url": "https://api.github.com/repos/phadej/github/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/phadej/github/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/phadej/github/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/phadej/github/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/phadej/github/contents/{+path}",+      "compare_url": "https://api.github.com/repos/phadej/github/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/phadej/github/merges",+      "archive_url": "https://api.github.com/repos/phadej/github/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/phadej/github/downloads",+      "issues_url": "https://api.github.com/repos/phadej/github/issues{/number}",+      "pulls_url": "https://api.github.com/repos/phadej/github/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/phadej/github/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/phadej/github/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/phadej/github/labels{/name}",+      "releases_url": "https://api.github.com/repos/phadej/github/releases{/id}",+      "deployments_url": "https://api.github.com/repos/phadej/github/deployments",+      "created_at": "2017-09-06T11:54:37Z",+      "updated_at": "2017-09-06T11:55:42Z",+      "pushed_at": "2017-10-01T16:58:54Z",+      "git_url": "git://github.com/phadej/github.git",+      "ssh_url": "git@github.com:phadej/github.git",+      "clone_url": "https://github.com/phadej/github.git",+      "svn_url": "https://github.com/phadej/github",+      "homepage": null,+      "size": 335,+      "stargazers_count": 0,+      "watchers_count": 0,+      "language": "Haskell",+      "has_issues": true,+      "has_projects": true,+      "has_downloads": true,+      "has_wiki": true,+      "has_pages": false,+      "forks_count": 0,+      "mirror_url": null,+      "open_issues_count": 1,+      "forks": 0,+      "open_issues": 1,+      "watchers": 0,+      "default_branch": "master"+    }+  },+  "base": {+    "label": "phadej:master",+    "ref": "master",+    "sha": "cb686149c0d88af16de61488a1ba70a6c71a2b65",+    "user": {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    },+    "repo": {+      "id": 102602684,+      "name": "github",+      "full_name": "phadej/github",+      "owner": {+        "login": "phadej",+        "id": 123898390,+        "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "private": true,+      "html_url": "https://github.com/phadej/github",+      "description": null,+      "fork": false,+      "url": "https://api.github.com/repos/phadej/github",+      "forks_url": "https://api.github.com/repos/phadej/github/forks",+      "keys_url": "https://api.github.com/repos/phadej/github/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/phadej/github/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/phadej/github/teams",+      "hooks_url": "https://api.github.com/repos/phadej/github/hooks",+      "issue_events_url": "https://api.github.com/repos/phadej/github/issues/events{/number}",+      "events_url": "https://api.github.com/repos/phadej/github/events",+      "assignees_url": "https://api.github.com/repos/phadej/github/assignees{/user}",+      "branches_url": "https://api.github.com/repos/phadej/github/branches{/branch}",+      "tags_url": "https://api.github.com/repos/phadej/github/tags",+      "blobs_url": "https://api.github.com/repos/phadej/github/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/phadej/github/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/phadej/github/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/phadej/github/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/phadej/github/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/phadej/github/languages",+      "stargazers_url": "https://api.github.com/repos/phadej/github/stargazers",+      "contributors_url": "https://api.github.com/repos/phadej/github/contributors",+      "subscribers_url": "https://api.github.com/repos/phadej/github/subscribers",+      "subscription_url": "https://api.github.com/repos/phadej/github/subscription",+      "commits_url": "https://api.github.com/repos/phadej/github/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/phadej/github/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/phadej/github/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/phadej/github/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/phadej/github/contents/{+path}",+      "compare_url": "https://api.github.com/repos/phadej/github/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/phadej/github/merges",+      "archive_url": "https://api.github.com/repos/phadej/github/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/phadej/github/downloads",+      "issues_url": "https://api.github.com/repos/phadej/github/issues{/number}",+      "pulls_url": "https://api.github.com/repos/phadej/github/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/phadej/github/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/phadej/github/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/phadej/github/labels{/name}",+      "releases_url": "https://api.github.com/repos/phadej/github/releases{/id}",+      "deployments_url": "https://api.github.com/repos/phadej/github/deployments",+      "created_at": "2017-09-06T11:54:37Z",+      "updated_at": "2017-09-06T11:55:42Z",+      "pushed_at": "2017-10-01T16:58:54Z",+      "git_url": "git://github.com/phadej/github.git",+      "ssh_url": "git@github.com:phadej/github.git",+      "clone_url": "https://github.com/phadej/github.git",+      "svn_url": "https://github.com/phadej/github",+      "homepage": null,+      "size": 335,+      "stargazers_count": 0,+      "watchers_count": 0,+      "language": "Haskell",+      "has_issues": true,+      "has_projects": true,+      "has_downloads": true,+      "has_wiki": true,+      "has_pages": false,+      "forks_count": 0,+      "mirror_url": null,+      "open_issues_count": 1,+      "forks": 0,+      "open_issues": 1,+      "watchers": 0,+      "default_branch": "master"+    }+  },+  "_links": {+    "self": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9"+    },+    "html": {+      "href": "https://github.com/phadej/github/pull/9"+    },+    "issue": {+      "href": "https://api.github.com/repos/phadej/github/issues/9"+    },+    "comments": {+      "href": "https://api.github.com/repos/phadej/github/issues/9/comments"+    },+    "review_comments": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9/comments"+    },+    "review_comment": {+      "href": "https://api.github.com/repos/phadej/github/pulls/comments{/number}"+    },+    "commits": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9/commits"+    },+    "statuses": {+      "href": "https://api.github.com/repos/phadej/github/statuses/20218048bb9529de09f1fdaa9126f60ffeb07ce5"+    }+  },+  "author_association": "OWNER",+  "merged": false,+  "mergeable": null,+  "rebaseable": null,+  "mergeable_state": "unknown",+  "merged_by": null,+  "comments": 0,+  "review_comments": 0,+  "maintainer_can_modify": false,+  "commits": 6,+  "additions": 363,+  "deletions": 48,+  "changed_files": 19+}
+ 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-review-requested.json view
@@ -0,0 +1,351 @@+{+  "url": "https://api.github.com/repos/phadej/github/pulls/9",+  "id": 144079630,+  "html_url": "https://github.com/phadej/github/pull/9",+  "diff_url": "https://github.com/phadej/github/pull/9.diff",+  "patch_url": "https://github.com/phadej/github/pull/9.patch",+  "issue_url": "https://api.github.com/repos/phadej/github/issues/9",+  "number": 9,+  "state": "open",+  "locked": false,+  "title": "Fetch my pull requests",+  "user": {+    "login": "phadej",+    "id": 123898390,+    "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+    "gravatar_id": "",+    "url": "https://api.github.com/users/phadej",+    "html_url": "https://github.com/phadej",+    "followers_url": "https://api.github.com/users/phadej/followers",+    "following_url": "https://api.github.com/users/phadej/following{/other_user}",+    "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+    "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+    "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+    "organizations_url": "https://api.github.com/users/phadej/orgs",+    "repos_url": "https://api.github.com/users/phadej/repos",+    "events_url": "https://api.github.com/users/phadej/events{/privacy}",+    "received_events_url": "https://api.github.com/users/phadej/received_events",+    "type": "User",+    "site_admin": false+  },+  "body": "",+  "created_at": "2017-10-01T17:22:12Z",+  "updated_at": "2017-10-01T17:22:12Z",+  "closed_at": null,+  "merged_at": null,+  "merge_commit_sha": null,+  "assignee": null,+  "assignees": [+    {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    }+  ],+  "requested_reviewers": [+    {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    }+  ],+  "milestone": null,+  "commits_url": "https://api.github.com/repos/phadej/github/pulls/9/commits",+  "review_comments_url": "https://api.github.com/repos/phadej/github/pulls/9/comments",+  "review_comment_url": "https://api.github.com/repos/phadej/github/pulls/comments{/number}",+  "comments_url": "https://api.github.com/repos/phadej/github/issues/9/comments",+  "statuses_url": "https://api.github.com/repos/phadej/github/statuses/20218048bb9529de09f1fdaa9126f60ffeb07ce5",+  "head": {+    "label": "phadej:fetch-my-pull-requests",+    "ref": "fetch-my-pull-requests",+    "sha": "20218048bb9529de09f1fdaa9126f60ffeb07ce5",+    "user": {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    },+    "repo": {+      "id": 102602684,+      "name": "github",+      "full_name": "phadej/github",+      "owner": {+        "login": "phadej",+        "id": 123898390,+        "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "private": true,+      "html_url": "https://github.com/phadej/github",+      "description": null,+      "fork": false,+      "url": "https://api.github.com/repos/phadej/github",+      "forks_url": "https://api.github.com/repos/phadej/github/forks",+      "keys_url": "https://api.github.com/repos/phadej/github/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/phadej/github/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/phadej/github/teams",+      "hooks_url": "https://api.github.com/repos/phadej/github/hooks",+      "issue_events_url": "https://api.github.com/repos/phadej/github/issues/events{/number}",+      "events_url": "https://api.github.com/repos/phadej/github/events",+      "assignees_url": "https://api.github.com/repos/phadej/github/assignees{/user}",+      "branches_url": "https://api.github.com/repos/phadej/github/branches{/branch}",+      "tags_url": "https://api.github.com/repos/phadej/github/tags",+      "blobs_url": "https://api.github.com/repos/phadej/github/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/phadej/github/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/phadej/github/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/phadej/github/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/phadej/github/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/phadej/github/languages",+      "stargazers_url": "https://api.github.com/repos/phadej/github/stargazers",+      "contributors_url": "https://api.github.com/repos/phadej/github/contributors",+      "subscribers_url": "https://api.github.com/repos/phadej/github/subscribers",+      "subscription_url": "https://api.github.com/repos/phadej/github/subscription",+      "commits_url": "https://api.github.com/repos/phadej/github/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/phadej/github/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/phadej/github/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/phadej/github/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/phadej/github/contents/{+path}",+      "compare_url": "https://api.github.com/repos/phadej/github/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/phadej/github/merges",+      "archive_url": "https://api.github.com/repos/phadej/github/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/phadej/github/downloads",+      "issues_url": "https://api.github.com/repos/phadej/github/issues{/number}",+      "pulls_url": "https://api.github.com/repos/phadej/github/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/phadej/github/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/phadej/github/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/phadej/github/labels{/name}",+      "releases_url": "https://api.github.com/repos/phadej/github/releases{/id}",+      "deployments_url": "https://api.github.com/repos/phadej/github/deployments",+      "created_at": "2017-09-06T11:54:37Z",+      "updated_at": "2017-09-06T11:55:42Z",+      "pushed_at": "2017-10-01T16:58:54Z",+      "git_url": "git://github.com/phadej/github.git",+      "ssh_url": "git@github.com:phadej/github.git",+      "clone_url": "https://github.com/phadej/github.git",+      "svn_url": "https://github.com/phadej/github",+      "homepage": null,+      "size": 335,+      "stargazers_count": 0,+      "watchers_count": 0,+      "language": "Haskell",+      "has_issues": true,+      "has_projects": true,+      "has_downloads": true,+      "has_wiki": true,+      "has_pages": false,+      "forks_count": 0,+      "mirror_url": null,+      "open_issues_count": 1,+      "forks": 0,+      "open_issues": 1,+      "watchers": 0,+      "default_branch": "master"+    }+  },+  "base": {+    "label": "phadej:master",+    "ref": "master",+    "sha": "cb686149c0d88af16de61488a1ba70a6c71a2b65",+    "user": {+      "login": "phadej",+      "id": 123898390,+      "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+      "gravatar_id": "",+      "url": "https://api.github.com/users/phadej",+      "html_url": "https://github.com/phadej",+      "followers_url": "https://api.github.com/users/phadej/followers",+      "following_url": "https://api.github.com/users/phadej/following{/other_user}",+      "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+      "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+      "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+      "organizations_url": "https://api.github.com/users/phadej/orgs",+      "repos_url": "https://api.github.com/users/phadej/repos",+      "events_url": "https://api.github.com/users/phadej/events{/privacy}",+      "received_events_url": "https://api.github.com/users/phadej/received_events",+      "type": "User",+      "site_admin": false+    },+    "repo": {+      "id": 102602684,+      "name": "github",+      "full_name": "phadej/github",+      "owner": {+        "login": "phadej",+        "id": 123898390,+        "avatar_url": "https://avatars3.githubusercontent.com/u/123898390?v=4",+        "gravatar_id": "",+        "url": "https://api.github.com/users/phadej",+        "html_url": "https://github.com/phadej",+        "followers_url": "https://api.github.com/users/phadej/followers",+        "following_url": "https://api.github.com/users/phadej/following{/other_user}",+        "gists_url": "https://api.github.com/users/phadej/gists{/gist_id}",+        "starred_url": "https://api.github.com/users/phadej/starred{/owner}{/repo}",+        "subscriptions_url": "https://api.github.com/users/phadej/subscriptions",+        "organizations_url": "https://api.github.com/users/phadej/orgs",+        "repos_url": "https://api.github.com/users/phadej/repos",+        "events_url": "https://api.github.com/users/phadej/events{/privacy}",+        "received_events_url": "https://api.github.com/users/phadej/received_events",+        "type": "User",+        "site_admin": false+      },+      "private": true,+      "html_url": "https://github.com/phadej/github",+      "description": null,+      "fork": false,+      "url": "https://api.github.com/repos/phadej/github",+      "forks_url": "https://api.github.com/repos/phadej/github/forks",+      "keys_url": "https://api.github.com/repos/phadej/github/keys{/key_id}",+      "collaborators_url": "https://api.github.com/repos/phadej/github/collaborators{/collaborator}",+      "teams_url": "https://api.github.com/repos/phadej/github/teams",+      "hooks_url": "https://api.github.com/repos/phadej/github/hooks",+      "issue_events_url": "https://api.github.com/repos/phadej/github/issues/events{/number}",+      "events_url": "https://api.github.com/repos/phadej/github/events",+      "assignees_url": "https://api.github.com/repos/phadej/github/assignees{/user}",+      "branches_url": "https://api.github.com/repos/phadej/github/branches{/branch}",+      "tags_url": "https://api.github.com/repos/phadej/github/tags",+      "blobs_url": "https://api.github.com/repos/phadej/github/git/blobs{/sha}",+      "git_tags_url": "https://api.github.com/repos/phadej/github/git/tags{/sha}",+      "git_refs_url": "https://api.github.com/repos/phadej/github/git/refs{/sha}",+      "trees_url": "https://api.github.com/repos/phadej/github/git/trees{/sha}",+      "statuses_url": "https://api.github.com/repos/phadej/github/statuses/{sha}",+      "languages_url": "https://api.github.com/repos/phadej/github/languages",+      "stargazers_url": "https://api.github.com/repos/phadej/github/stargazers",+      "contributors_url": "https://api.github.com/repos/phadej/github/contributors",+      "subscribers_url": "https://api.github.com/repos/phadej/github/subscribers",+      "subscription_url": "https://api.github.com/repos/phadej/github/subscription",+      "commits_url": "https://api.github.com/repos/phadej/github/commits{/sha}",+      "git_commits_url": "https://api.github.com/repos/phadej/github/git/commits{/sha}",+      "comments_url": "https://api.github.com/repos/phadej/github/comments{/number}",+      "issue_comment_url": "https://api.github.com/repos/phadej/github/issues/comments{/number}",+      "contents_url": "https://api.github.com/repos/phadej/github/contents/{+path}",+      "compare_url": "https://api.github.com/repos/phadej/github/compare/{base}...{head}",+      "merges_url": "https://api.github.com/repos/phadej/github/merges",+      "archive_url": "https://api.github.com/repos/phadej/github/{archive_format}{/ref}",+      "downloads_url": "https://api.github.com/repos/phadej/github/downloads",+      "issues_url": "https://api.github.com/repos/phadej/github/issues{/number}",+      "pulls_url": "https://api.github.com/repos/phadej/github/pulls{/number}",+      "milestones_url": "https://api.github.com/repos/phadej/github/milestones{/number}",+      "notifications_url": "https://api.github.com/repos/phadej/github/notifications{?since,all,participating}",+      "labels_url": "https://api.github.com/repos/phadej/github/labels{/name}",+      "releases_url": "https://api.github.com/repos/phadej/github/releases{/id}",+      "deployments_url": "https://api.github.com/repos/phadej/github/deployments",+      "created_at": "2017-09-06T11:54:37Z",+      "updated_at": "2017-09-06T11:55:42Z",+      "pushed_at": "2017-10-01T16:58:54Z",+      "git_url": "git://github.com/phadej/github.git",+      "ssh_url": "git@github.com:phadej/github.git",+      "clone_url": "https://github.com/phadej/github.git",+      "svn_url": "https://github.com/phadej/github",+      "homepage": null,+      "size": 335,+      "stargazers_count": 0,+      "watchers_count": 0,+      "language": "Haskell",+      "has_issues": true,+      "has_projects": true,+      "has_downloads": true,+      "has_wiki": true,+      "has_pages": false,+      "forks_count": 0,+      "mirror_url": null,+      "open_issues_count": 1,+      "forks": 0,+      "open_issues": 1,+      "watchers": 0,+      "default_branch": "master"+    }+  },+  "_links": {+    "self": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9"+    },+    "html": {+      "href": "https://github.com/phadej/github/pull/9"+    },+    "issue": {+      "href": "https://api.github.com/repos/phadej/github/issues/9"+    },+    "comments": {+      "href": "https://api.github.com/repos/phadej/github/issues/9/comments"+    },+    "review_comments": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9/comments"+    },+    "review_comment": {+      "href": "https://api.github.com/repos/phadej/github/pulls/comments{/number}"+    },+    "commits": {+      "href": "https://api.github.com/repos/phadej/github/pulls/9/commits"+    },+    "statuses": {+      "href": "https://api.github.com/repos/phadej/github/statuses/20218048bb9529de09f1fdaa9126f60ffeb07ce5"+    }+  },+  "author_association": "OWNER",+  "merged": false,+  "mergeable": null,+  "rebaseable": null,+  "mergeable_state": "unknown",+  "merged_by": null,+  "comments": 0,+  "review_comments": 0,+  "maintainer_can_modify": false,+  "commits": 6,+  "additions": 363,+  "deletions": 48,+  "changed_files": 19+}
+ 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"+}
+ fixtures/user-organizations.json view
@@ -0,0 +1,9 @@+[+  {+    "login": "github",+    "id": 1,+    "url": "https://api.github.com/orgs/github",+    "avatar_url": "https://github.com/images/error/octocat_happy.gif",+    "description": "A great organization"+  }+]
+ fixtures/user.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": "User",+  "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,219 +1,271 @@--- github.cabal auto-generated by cabal init. For additional options,--- see--- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.--- The name of the package.-Name:                github---- The package version. See the Haskell package versioning policy--- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for--- standards guiding when and how versions should be incremented.-Version:             0.13.2---- A short (one-line) description of the package.-Synopsis:            Access to the Github API, v3.---- A longer description of the package.-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-                     like references and trees. This library wraps all of that, exposing a basic but-                     Haskell-friendly set of functions and data structures.-                     .-                     For more of an overview please see the README: <https://github.com/jwiegley/github/blob/master/README.md>---- The license under which the package is released.-License:             BSD3---- The file containing the license text.-License-file:        LICENSE---- The package author(s).-Author:              Mike Burns, John Wiegley---- An email address to which users can send suggestions, bug reports,--- and patches.-Maintainer:          johnw@newartisans.com+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+  like references and trees. This library wraps all of that, exposing a basic but+  Haskell-friendly set of functions and data structures.+  .+  For supported endpoints see "GitHub" module.+  .+  > import qualified GitHub as GH+  >+  > main :: IO ()+  > main = do+  >     possibleUser <- GH.github' GH.userInfoForR "phadej"+  >     print possibleUser+  .+  For more of an overview please see the README: <https://github.com/haskell-github/github/blob/master/README.md> -Homepage:            https://github.com/jwiegley/github+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 --- A copyright notice.-Copyright:           Copyright 2012-2013 Mike Burns, Copyright 2013-2015 John Wiegley+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 -Category:            Network APIs+extra-doc-files:+  README.md+  CHANGELOG.md -Build-type:          Simple+extra-source-files:+  fixtures/**/*.json --- Extra files to be distributed with the package, such as examples or--- a README.-Extra-source-files:  README.md-                    ,samples/Gists/Comments/ShowComment.hs-                    ,samples/Gists/Comments/ShowComments.hs-                    ,samples/Gists/ListGists.hs-                    ,samples/Gists/ShowGist.hs-                    ,samples/GitData/Commits/GitShow.hs-                    ,samples/GitData/References/GitCreateReference.hs-                    ,samples/GitData/References/GitLsRemote.hs-                    ,samples/GitData/References/GitLsRemoteTags.hs-                    ,samples/GitData/References/GitLsRemoteWithRef.hs-                    ,samples/GitData/Trees/GitLsTree.hs-                    ,samples/GitData/Trees/GitLsTreeRecursively.hs-                    ,samples/Issues/Comments/ShowComment.hs-                    ,samples/Issues/Comments/ShowComments.hs-                    ,samples/Issues/Events/ShowEvent.hs-                    ,samples/Issues/Events/ShowIssueEvents.hs-                    ,samples/Issues/Events/ShowRepoEvents.hs-                    ,samples/Issues/Labels/ShowIssueLabels.hs-                    ,samples/Issues/Labels/ShowLabel.hs-                    ,samples/Issues/Labels/ShowMilestoneLabels.hs-                    ,samples/Issues/Labels/ShowRepoLabels.hs-                    ,samples/Issues/Milestones/ShowMilestone.hs-                    ,samples/Issues/Milestones/ShowMilestones.hs-                    ,samples/Issues/ShowIssue.hs-                    ,samples/Issues/ShowRepoIssues.hs-                    ,samples/Organizations/Members/ShowMembers.hs-                    ,samples/Organizations/ShowPublicOrganization.hs-                    ,samples/Organizations/ShowPublicOrganizations.hs-                    ,samples/Pulls/Diff.hs-                    ,samples/Pulls/ListPulls.hs-                    ,samples/Pulls/ReviewComments/ListComments.hs-                    ,samples/Pulls/ReviewComments/ShowComment.hs-                    ,samples/Pulls/ShowCommits.hs-                    ,samples/Pulls/ShowPull.hs-                    ,samples/Search/SearchRepos.hs-                    ,samples/Repos/Collaborators/IsCollaborator.hs-                    ,samples/Repos/Collaborators/ListCollaborators.hs-                    ,samples/Repos/Commits/CommitComment.hs-                    ,samples/Repos/Commits/CommitComments.hs-                    ,samples/Repos/Commits/GitDiff.hs-                    ,samples/Repos/Commits/GitLog.hs-                    ,samples/Repos/Commits/GitShow.hs-                    ,samples/Repos/Commits/RepoComments.hs-                    ,samples/Repos/Forks/ListForks.hs-                    ,samples/Repos/ListBranches.hs-                    ,samples/Repos/ListContributors.hs-                    ,samples/Repos/ListContributorsWithAnonymous.hs-                    ,samples/Repos/ListLanguages.hs-                    ,samples/Repos/ListOrgRepos.hs-                    ,samples/Repos/ListTags.hs-                    ,samples/Repos/ListUserRepos.hs-                    ,samples/Repos/ShowRepo.hs-                    ,samples/Repos/Watching/ListWatched.hs-                    ,samples/Repos/Watching/ListWatchers.hs-                    ,samples/Repos/Starring/ListStarred.hs-                    ,samples/Repos/Webhooks/CreateWebhook.hs-                    ,samples/Repos/Webhooks/DeleteWebhook.hs-                    ,samples/Repos/Webhooks/EditWebhook.hs-                    ,samples/Repos/Webhooks/ListWebhook.hs-                    ,samples/Repos/Webhooks/ListWebhooks.hs-                    ,samples/Repos/Webhooks/PingWebhook.hs-                    ,samples/Repos/Webhooks/TestPushWebhook.hs-                    ,samples/Users/Followers/ListFollowers.hs-                    ,samples/Users/Followers/ListFollowing.hs-                    ,samples/Users/ShowUser.hs-                    ,LICENSE+source-repository head+  type:     git+  location: https://github.com/haskell-github/github.git +flag openssl+  description: "Use http-client-openssl"+  manual:      True+  default:     False --- Constraint on the version of Cabal needed to build this package.-Cabal-version:       >=1.10+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 -source-repository head-  type: git-  location: git://github.com/jwiegley/github.git+  other-extensions:+    CPP+    FlexibleContexts+    FlexibleInstances+    GADTs+    KindSignatures+    RecordWildCards+    StandaloneDeriving -Library-  -- Modules exported by the library.-  Default-Language: Haskell2010-  Exposed-modules: Github.Auth,-                   Github.Data,-                   Github.Data.Definitions,-                   Github.Events,-                   Github.Gists,-                   Github.Gists.Comments,-                   Github.GitData.Commits,-                   Github.GitData.References,-                   Github.GitData.Trees,-                   Github.GitData.Blobs,-                   Github.Issues,-                   Github.Issues.Comments,-                   Github.Issues.Events,-                   Github.Issues.Labels,-                   Github.Issues.Milestones,-                   Github.Organizations,-                   Github.Organizations.Members,-                   Github.PullRequests,-                   Github.Repos,-                   Github.Repos.Collaborators,-                   Github.Repos.Commits,-                   Github.Repos.Forks,-                   Github.Repos.Watching,-                   Github.Repos.Starring,-                   Github.Repos.Subscribing,-                   Github.Repos.Webhooks-                   Github.Repos.Webhooks.Validate,-                   Github.Users,-                   Github.Users.Followers-                   Github.Search+  exposed-modules:+    GitHub+    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+    GitHub.Data.Id+    GitHub.Data.Invitation+    GitHub.Data.Issues+    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+    GitHub.Data.Reviews+    GitHub.Data.Search+    GitHub.Data.Statuses+    GitHub.Data.Teams+    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+    GitHub.Endpoints.GitData.Commits+    GitHub.Endpoints.GitData.References+    GitHub.Endpoints.GitData.Trees+    GitHub.Endpoints.Issues+    GitHub.Endpoints.Issues.Comments+    GitHub.Endpoints.Issues.Events+    GitHub.Endpoints.Issues.Labels+    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.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+    GitHub.Endpoints.Search+    GitHub.Endpoints.Users+    GitHub.Endpoints.Users.Emails+    GitHub.Endpoints.Users.Followers+    GitHub.Endpoints.Users.PublicSSHKeys+    GitHub.Enterprise+    GitHub.Internal.Prelude+    GitHub.Request -  -- Packages needed in order to build this package.-  Build-depends: base >= 4.0 && < 5.0,-                 time,-                 aeson >= 0.6.1.0,-                 attoparsec >= 0.10.3.0,-                 bytestring,-                 case-insensitive >= 0.4.0.4,-                 containers,-                 hashable,-                 text,-                 old-locale,-                 HTTP,-                 network,-                 http-conduit >= 1.8,-                 conduit,-                 failure,-                 http-types,-                 data-default,-                 vector,-                 unordered-containers >= 0.2 && < 0.3,-                 cryptohash >= 0.11,-                 byteable >= 0.1.0,-                 base16-bytestring >= 0.1.1.6+  other-modules:   Paths_github+  autogen-modules: Paths_github -  -- Modules not exported by this package.-  Other-modules:       Github.Private+  -- 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.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 -  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.-  -- Build-tools:+  -- other packages+  build-depends:+      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 -  GHC-Options: -Wall -fno-warn-orphans+  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 +  else+    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, .-  main-is: Spec.hs-  build-depends: base >= 4.0 && < 5.0,-                 time,-                 aeson >= 0.6.1.0,-                 attoparsec >= 0.10.3.0,-                 bytestring,-                 case-insensitive >= 0.4.0.4,-                 containers,-                 hashable,-                 text,-                 old-locale,-                 HTTP,-                 network,-                 http-conduit >= 1.8,-                 conduit,-                 failure,-                 http-types,-                 data-default,-                 vector,-                 unordered-containers >= 0.2 && < 0.3,-                 cryptohash >= 0.11,-                 byteable >= 0.1.0,-                 base16-bytestring >= 0.1.1.6--                 , hspec+  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.EventsSpec+    GitHub.IssuesSpec+    GitHub.OrganizationsSpec+    GitHub.PublicSSHKeysSpec+    GitHub.PullRequestReviewsSpec+    GitHub.PullRequestsSpec+    GitHub.RateLimitSpec+    GitHub.ReleasesSpec+    GitHub.ReposSpec+    GitHub.ReviewDecodeSpec+    GitHub.SearchSpec+    GitHub.UsersSpec -  ghc-options: -Wall -fno-warn-orphans+  build-depends:+      aeson+    , base+    , base-compat+    , bytestring+    , file-embed+    , github+    , hspec                 >=2.6.1 && <2.12+    , http-client+    , tagged+    , text+    , unordered-containers+    , vector
− samples/Gists/Comments/ShowComment.hs
@@ -1,16 +0,0 @@-module ShowComment where--import qualified Github.Gists.Comments as Github--main = do-  possibleComment <- Github.comment "62449"-  case possibleComment of-    (Left error)  -> putStrLn $ "Error: " ++ (show error)-    (Right comment) -> putStrLn $ formatComment comment--formatComment comment =-  (Github.githubOwnerLogin $ Github.gistCommentUser comment) ++ "\n" ++-    (formatGithubDate $ Github.gistCommentUpdatedAt comment) ++ "\n\n" ++-    (Github.gistCommentBody comment)--formatGithubDate = show . Github.fromGithubDate
− samples/Gists/Comments/ShowComments.hs
@@ -1,17 +0,0 @@-module ShowComments where--import qualified Github.Gists.Comments as Github-import Data.List (intercalate)--main = do-  possibleComments <- Github.commentsOn "1174060"-  case possibleComments of-    (Left error)  -> putStrLn $ "Error: " ++ (show error)-    (Right comments) -> putStrLn $ intercalate "\n\n" $ map formatComment comments--formatComment comment =-  (Github.githubOwnerLogin $ Github.gistCommentUser comment) ++ "\n" ++-    (formatGithubDate $ Github.gistCommentUpdatedAt comment) ++ "\n\n" ++-    (Github.gistCommentBody comment)--formatGithubDate = show . Github.fromGithubDate
− samples/Gists/ListGists.hs
@@ -1,15 +0,0 @@-module ListGists where--import qualified Github.Gists as Github-import Data.List (intercalate)--main = do-  possibleGists <- Github.gists "mike-burns"-  case possibleGists of-    (Left error)  -> putStrLn $ "Error: " ++ (show error)-    (Right gists) -> putStrLn $ intercalate "\n\n" $ map formatGist gists--formatGist gist =-  (Github.gistId gist) ++ "\n" ++-    (maybe "indescribable" id $ Github.gistDescription gist) ++ "\n" ++-    (Github.gistHtmlUrl gist)
− samples/Gists/ShowGist.hs
@@ -1,20 +0,0 @@-module ShowGist where--import qualified Github.Gists as Github-import Data.List (intercalate)--main = do-  possibleGist <- Github.gist "23084"-  case possibleGist of-    (Left error)  -> putStrLn $ "Error: " ++ (show error)-    (Right gist) -> putStrLn $ formatGist gist--formatGist gist =-  (Github.gistId gist) ++ "\n" ++-    (maybe "indescribable" id $ Github.gistDescription gist) ++ "\n" ++-    (Github.gistHtmlUrl gist) ++ "\n\n" ++-    (intercalate "\n\n" $ map formatGistFile $ Github.gistFiles gist)--formatGistFile gistFile =-  (Github.gistFileFilename gistFile) ++ ":\n" ++-    maybe "[empty]" id (Github.gistFileContent gistFile)
− samples/GitData/Commits/GitShow.hs
@@ -1,23 +0,0 @@-module GitShow where--import qualified Github.GitData.Commits as Github-import Data.Maybe (fromJust)--main = do-  possibleCommit <- Github.commit "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-  case possibleCommit of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right commit) -> putStrLn $ formatCommit commit--formatCommit :: Github.GitCommit -> String-formatCommit commit =-  "commit " ++ (fromJust $ Github.gitCommitSha commit) ++-    "\nAuthor: " ++ (formatAuthor author) ++-    "\nDate:   " ++ (show $ Github.fromGithubDate $ Github.gitUserDate author) ++-    "\n\n\t" ++ (Github.gitCommitMessage commit) ++ "\n"-  where author = Github.gitCommitAuthor commit--formatAuthor :: Github.GitUser -> String-formatAuthor author =-  (Github.gitUserName author) ++ " <" ++ (Github.gitUserEmail author) ++ ">"-
− samples/GitData/References/GitCreateReference.hs
@@ -1,19 +0,0 @@-module GitCreateRef where--import qualified Github.Auth as Auth-import Github.GitData.References--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  newlyCreatedGitRef <- createReference auth "myrepo" "myowner" NewGitReference {-       newGitReferenceRef = "refs/heads/fav_tag"-      ,newGitReferenceSha = "aa218f56b14c9653891f9e74264a383fa43fefbd"-    }-  case newlyCreatedGitRef of-   (Left err) -> putStrLn $ "Error: " ++ show err-   (Right newRef) -> putStrLn . formatReference $ newRef-                        -formatReference :: GitReference -> String-formatReference ref  =-  (gitObjectSha $ gitReferenceObject ref) ++ "\t" ++ (gitReferenceRef ref)
− samples/GitData/References/GitLsRemote.hs
@@ -1,16 +0,0 @@-module GitLsRemote where--import qualified Github.GitData.References as Github-import Data.List (intercalate)--main = do-  possibleReferences <- Github.references "mike-burns" "github"-  case possibleReferences of-       (Left error)       -> putStrLn $ "Error: " ++ show error-       (Right references) -> do-         putStrLn "From git@github.com:mike-burns/github.git"-         putStrLn $ intercalate "\n" $ map formatReference references--formatReference reference =-  (Github.gitObjectSha $ Github.gitReferenceObject reference) ++-    "\t" ++ (Github.gitReferenceRef reference)
− samples/GitData/References/GitLsRemoteTags.hs
@@ -1,17 +0,0 @@-module GitLsRemoteTags where--import qualified Github.GitData.References as Github-import Data.List (intercalate)--main = do-  possibleReferences <- Github.namespacedReferences "thoughtbot" "paperclip" "tags"-  case possibleReferences of-       (Left error)       -> putStrLn $ "Error: " ++ show error-       (Right references) -> do-         putStrLn "From git@github.com:thoughtbot/paperclip.git"-         putStrLn $ intercalate "\n" $ map formatReference references--formatReference reference =-  (Github.gitObjectSha $ Github.gitReferenceObject reference) ++-    "\t" ++ (Github.gitReferenceRef reference)-
− samples/GitData/References/GitLsRemoteWithRef.hs
@@ -1,13 +0,0 @@-module GitLsRemoteWithRef where--import qualified Github.GitData.References as Github--main = do-  possibleReference <- Github.reference "mike-burns" "github" "heads/master"-  putStrLn $ either (\e -> "Error: " ++ show e)-                    formatReference-                    possibleReference--formatReference reference =-  (Github.gitObjectSha $ Github.gitReferenceObject reference) ++-    "\t" ++ (Github.gitReferenceRef reference)
− samples/GitData/Trees/GitLsTree.hs
@@ -1,19 +0,0 @@-module GitLsTree where--import qualified Github.GitData.Trees as Github-import Data.List (intercalate)--main = do-  possibleTree <- Github.tree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-  case possibleTree of-       (Left error)  -> putStrLn $ "Error: " ++ show error-       (Right tree) -> putStrLn $ formatTree tree--formatTree tree =-  intercalate "\n" $ map formatGitTree $ Github.treeGitTrees tree--formatGitTree gitTree =-  (Github.gitTreeMode gitTree) ++ " " ++-    (Github.gitTreeType gitTree) ++ " " ++-    (Github.gitTreeSha gitTree) ++ "\t" ++-    (Github.gitTreePath gitTree)
− samples/GitData/Trees/GitLsTreeRecursively.hs
@@ -1,19 +0,0 @@-module GitLsTreeRecursively where--import qualified Github.GitData.Trees as Github-import Data.List (intercalate)--main = do-  possibleTree <- Github.nestedTree "thoughtbot" "paperclip" "fe114451f7d066d367a1646ca7ac10e689b46844"-  case possibleTree of-       (Left error)  -> putStrLn $ "Error: " ++ show error-       (Right tree) -> putStrLn $ formatTree tree--formatTree tree =-  intercalate "\n" $ map formatGitTree $ Github.treeGitTrees tree--formatGitTree gitTree =-  (Github.gitTreeMode gitTree) ++ " " ++-    (Github.gitTreeType gitTree) ++ " " ++-    (Github.gitTreeSha gitTree) ++ "\t" ++-    (Github.gitTreePath gitTree)
− samples/Issues/Comments/ShowComment.hs
@@ -1,15 +0,0 @@-module ShowComment where--import qualified Github.Issues.Comments as Github--main = do-  possibleComment <- Github.comment "thoughtbot" "paperclip" 1468184-  putStrLn $ either (\e -> "Error: " ++ show e)-                    formatComment-                    possibleComment--formatComment comment =-  (Github.githubOwnerLogin $ Github.issueCommentUser comment) ++-    " commented " ++-    (show $ Github.fromGithubDate $ Github.issueCommentUpdatedAt comment) ++-    "\n" ++ (Github.issueCommentBody comment)
− samples/Issues/Comments/ShowComments.hs
@@ -1,17 +0,0 @@-module ShowComments where--import qualified Github.Issues.Comments as Github-import Data.List (intercalate)--main = do-  possibleComments <- Github.comments "thoughtbot" "paperclip" 635-  case possibleComments of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right issues) ->-         putStrLn $ intercalate "\n\n" $ map formatComment issues--formatComment comment =-  (Github.githubOwnerLogin $ Github.issueCommentUser comment) ++-    " commented " ++-    (show $ Github.fromGithubDate $ Github.issueCommentUpdatedAt comment) ++-    "\n" ++ (Github.issueCommentBody comment)
− samples/Issues/Events/ShowEvent.hs
@@ -1,38 +0,0 @@-module ShowEvents where--import qualified Github.Issues.Events as Github-import Data.List (intercalate)-import Data.Maybe (fromJust)--main = do-  possibleEvent <- Github.event "thoughtbot" "paperclip" 5335772-  case possibleEvent of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right event) -> do-         putStrLn $ formatEvent event--formatEvent event = formatEvent' event (Github.eventType event)-  where-  formatEvent' event Github.Closed =-    "Closed on " ++ createdAt event ++ " by " ++ loginName event ++-      withCommitId event (\commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Reopened =-    "Reopened on " ++ createdAt event ++ " by " ++ loginName event-  formatEvent' event Github.Subscribed =-    loginName event ++ " is subscribed to receive notifications"-  formatEvent' event Github.Unsubscribed =-    loginName event ++ " is unsubscribed from notifications"-  formatEvent' event Github.Merged =-    "Issue merged by " ++ loginName event ++ " on " ++ createdAt event ++-      (withCommitId event $ \commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Referenced =-    withCommitId event $ \commitId ->-      "Issue referenced from " ++ commitId ++ " by " ++ loginName event-  formatEvent' event Github.Mentioned =-    loginName event ++ " was mentioned in the issue's body"-  formatEvent' event Github.Assigned =-    "Issue assigned to " ++ loginName event ++ " on " ++ createdAt event--loginName = Github.githubOwnerLogin . Github.eventActor-createdAt = show . Github.fromGithubDate . Github.eventCreatedAt-withCommitId event f = maybe "" f (Github.eventCommitId event)
− samples/Issues/Events/ShowIssueEvents.hs
@@ -1,38 +0,0 @@-module ShowIssueEvents where--import qualified Github.Issues.Events as Github-import Data.List (intercalate)--main = do-  possibleEvents <- Github.eventsForIssue "thoughtbot" "paperclip" 49-  case possibleEvents of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right events) -> do-         putStrLn "Issue #49:\n"-         putStrLn $ intercalate "\n" $ map formatEvent events--formatEvent event = formatEvent' event (Github.eventType event)-  where-  formatEvent' event Github.Closed =-    "Closed on " ++ createdAt event ++ " by " ++ loginName event ++-      withCommitId event (\commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Reopened =-    "Reopened on " ++ createdAt event ++ " by " ++ loginName event-  formatEvent' event Github.Subscribed =-    loginName event ++ " is subscribed to receive notifications"-  formatEvent' event Github.Unsubscribed =-    loginName event ++ " is unsubscribed from notifications"-  formatEvent' event Github.Merged =-    "Issue merged by " ++ loginName event ++ " on " ++ createdAt event ++-      (withCommitId event $ \commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Referenced =-    withCommitId event $ \commitId ->-      "Issue referenced from " ++ commitId ++ " by " ++ loginName event-  formatEvent' event Github.Mentioned =-    loginName event ++ " was mentioned in the issue's body"-  formatEvent' event Github.Assigned =-    "Issue assigned to " ++ loginName event ++ " on " ++ createdAt event--loginName = Github.githubOwnerLogin . Github.eventActor-createdAt = show . Github.fromGithubDate . Github.eventCreatedAt-withCommitId event f = maybe "" f (Github.eventCommitId event)
− samples/Issues/Events/ShowRepoEvents.hs
@@ -1,41 +0,0 @@-module ShowRepoEvents where--import qualified Github.Issues.Events as Github-import Data.List (intercalate)-import Data.Maybe (fromJust)--main = do-  possibleEvents <- Github.eventsForRepo "thoughtbot" "paperclip"-  case possibleEvents of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right events) -> do-         putStrLn $ intercalate "\n" $ map formatEvent events--formatEvent event =-  "Issue #" ++ issueNumber event ++ ": " ++-    formatEvent' event (Github.eventType event)-  where-  formatEvent' event Github.Closed =-    "closed on " ++ createdAt event ++ " by " ++ loginName event ++-      withCommitId event (\commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Reopened =-    "reopened on " ++ createdAt event ++ " by " ++ loginName event-  formatEvent' event Github.Subscribed =-    loginName event ++ " is subscribed to receive notifications"-  formatEvent' event Github.Unsubscribed =-    loginName event ++ " is unsubscribed from notifications"-  formatEvent' event Github.Merged =-    "merged by " ++ loginName event ++ " on " ++ createdAt event ++-      (withCommitId event $ \commitId -> " in the commit " ++ commitId)-  formatEvent' event Github.Referenced =-    withCommitId event $ \commitId ->-      "referenced from " ++ commitId ++ " by " ++ loginName event-  formatEvent' event Github.Mentioned =-    loginName event ++ " was mentioned in the issue's body"-  formatEvent' event Github.Assigned =-    "assigned to " ++ loginName event ++ " on " ++ createdAt event--loginName = Github.githubOwnerLogin . Github.eventActor-createdAt = show . Github.fromGithubDate . Github.eventCreatedAt-withCommitId event f = maybe "" f (Github.eventCommitId event)-issueNumber = show . Github.issueNumber . fromJust . Github.eventIssue
− samples/Issues/Labels/ShowIssueLabels.hs
@@ -1,14 +0,0 @@-module ShowIssueLabels where--import qualified Github.Issues.Labels as Github-import Data.List (intercalate)--main = do-  possibleLabels <- Github.labelsOnIssue "thoughtbot" "paperclip" 585-  case possibleLabels of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right labels) -> do-         putStrLn $ intercalate "\n" $ map formatLabel labels--formatLabel label =-  (Github.labelName label) ++ ", colored " ++ (Github.labelColor label)
− samples/Issues/Labels/ShowLabel.hs
@@ -1,13 +0,0 @@-module ShowLabel where--import qualified Github.Issues.Labels as Github--main = do-  possibleLabel <- Github.label "thoughtbot" "paperclip" "bug"-  case possibleLabel of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right label) -> putStrLn $ formatLabel label--formatLabel label =-  (Github.labelName label) ++ ", colored " ++ (Github.labelColor label)-
− samples/Issues/Labels/ShowMilestoneLabels.hs
@@ -1,15 +0,0 @@-module ShowMilestoneLabels where--import qualified Github.Issues.Labels as Github-import Data.List (intercalate)--main = do-  possibleLabels <- Github.labelsOnMilestone "thoughtbot" "paperclip" 2-  case possibleLabels of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right labels) -> do-         putStrLn $ intercalate "\n" $ map formatLabel labels--formatLabel label =-  (Github.labelName label) ++ ", colored " ++ (Github.labelColor label)-
− samples/Issues/Labels/ShowRepoLabels.hs
@@ -1,14 +0,0 @@-module ShowRepoLabels where--import qualified Github.Issues.Labels as Github-import Data.List (intercalate)--main = do-  possibleLabels <- Github.labelsOnRepo "thoughtbot" "paperclip"-  case possibleLabels of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right labels) -> do-         putStrLn $ intercalate "\n" $ map formatLabel labels--formatLabel label =-  (Github.labelName label) ++ ", colored " ++ (Github.labelColor label)
− samples/Issues/Milestones/ShowMilestone.hs
@@ -1,24 +0,0 @@-module ShowMilestone where--import qualified Github.Issues.Milestones as Github-import Data.List (intercalate)--main = do-  possibleMilestone <- Github.milestone "thoughtbot" "paperclip" 2-  case possibleMilestone of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right milestone) ->-         putStrLn $ formatMilestone milestone--formatMilestone milestone =-  (Github.milestoneTitle milestone) ++ ", as created by " ++-    (loginName milestone) ++ " on " ++ (createdAt milestone) ++-    formatDueOn (Github.milestoneDueOn milestone) ++ " and has the " ++-    (Github.milestoneState milestone) ++ " status"--formatDueOn Nothing = ""-formatDueOn (Just milestoneDate) = ", is due on " ++ dueOn milestoneDate--loginName = Github.githubOwnerLogin . Github.milestoneCreator-createdAt = show . Github.fromGithubDate . Github.milestoneCreatedAt-dueOn = show . Github.fromGithubDate
− samples/Issues/Milestones/ShowMilestones.hs
@@ -1,24 +0,0 @@-module ShowMilestones where--import qualified Github.Issues.Milestones as Github-import Data.List (intercalate)--main = do-  possibleMilestones <- Github.milestones "thoughtbot" "paperclip"-  case possibleMilestones of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right milestones) ->-         putStrLn $ intercalate "\n\n" $ map formatMilestone milestones--formatMilestone milestone =-  (Github.milestoneTitle milestone) ++ ", as created by " ++-    (loginName milestone) ++ " on " ++ (createdAt milestone) ++-    formatDueOn (Github.milestoneDueOn milestone) ++ " and has the " ++-    (Github.milestoneState milestone) ++ " status"--formatDueOn Nothing = ""-formatDueOn (Just milestoneDate) = ", is due on " ++ dueOn milestoneDate--loginName = Github.githubOwnerLogin . Github.milestoneCreator-createdAt = show . Github.fromGithubDate . Github.milestoneCreatedAt-dueOn = show . Github.fromGithubDate
− samples/Issues/ShowIssue.hs
@@ -1,17 +0,0 @@-module ShowIssue where--import qualified Github.Issues as Github--main = do-  possibleIssue <- Github.issue "thoughtbot" "paperclip" 549-  putStrLn $ either (\e -> "Error: " ++ show e)-                    formatIssue-                    possibleIssue--formatIssue issue =-  (Github.githubOwnerLogin $ Github.issueUser issue) ++-    " opened this issue " ++-    (show $ Github.fromGithubDate $ Github.issueCreatedAt issue) ++ "\n" ++-    (Github.issueState issue) ++ " with " ++-    (show $ Github.issueComments issue) ++ " comments" ++ "\n\n" ++-    (Github.issueTitle issue)
− samples/Issues/ShowRepoIssues.hs
@@ -1,21 +0,0 @@-module ShowRepoIssue where--import qualified Github.Issues as Github-import Data.List (intercalate)--main = do-  let limitations = [Github.OnlyClosed, Github.Mentions "mike-burns", Github.AssignedTo "jyurek"]-  possibleIssues <- Github.issuesForRepo "thoughtbot" "paperclip" limitations-  case possibleIssues of-       (Left error) -> putStrLn $ "Error: " ++ show error-       (Right issues) ->-         putStrLn $ intercalate "\n\n" $ map formatIssue issues--formatIssue issue =-  (Github.githubOwnerLogin $ Github.issueUser issue) ++-    " opened this issue " ++-    (show $ Github.fromGithubDate $ Github.issueCreatedAt issue) ++ "\n" ++-    (Github.issueState issue) ++ " with " ++-    (show $ Github.issueComments issue) ++ " comments" ++ "\n\n" ++-    (Github.issueTitle issue)-
− samples/Organizations/Members/ShowMembers.hs
@@ -1,11 +0,0 @@-module ShowMembers where--import qualified Github.Organizations.Members as Github-import Data.List (intercalate)--main = do-  possibleMembers <- Github.membersOf "thoughtbot"-  case possibleMembers of-       (Left error)  -> putStrLn $ "Error: " ++ (show error)-       (Right members) ->-         putStrLn $ intercalate "\n" $ map Github.githubOwnerLogin members
− samples/Organizations/ShowPublicOrganization.hs
@@ -1,15 +0,0 @@-module ShowPublicOrganization where--import qualified Github.Organizations as Github--main = do-  possibleOrganization <- Github.publicOrganization "thoughtbot"-  case possibleOrganization of-       (Left error)  -> putStrLn $ "Error: " ++ (show error)-       (Right organization) ->-         putStrLn $ formatOrganization organization--formatOrganization organization =-  (maybe "" (\s -> s ++ "\n") (Github.organizationName organization)) ++-    (Github.organizationHtmlUrl organization) ++-    (maybe "" (\s -> "\n" ++ s) (Github.organizationBlog organization))
− samples/Organizations/ShowPublicOrganizations.hs
@@ -1,13 +0,0 @@-module ShowPublicOrganizations where--import qualified Github.Organizations as Github-import Data.List (intercalate)--main = do-  possibleOrganizations <- Github.publicOrganizationsFor "mike-burns"-  case possibleOrganizations of-       (Left error)  -> putStrLn $ "Error: " ++ (show error)-       (Right organizations) ->-         putStrLn $ intercalate "\n" $ map formatOrganization organizations--formatOrganization = Github.simpleOrganizationLogin
− samples/Pulls/Diff.hs
@@ -1,13 +0,0 @@-module Diff where--import qualified Github.PullRequests as Github-import Data.List--main = do-  possiblePullRequestFiles <- Github.pullRequestFiles "thoughtbot" "paperclip" 575-  case possiblePullRequestFiles of-       (Left error)    -> putStrLn $ "Error: " ++ (show error)-       (Right files) -> putStrLn $ intercalate "\n\n" $ map formatFile files--formatFile file =-  Github.fileFilename file ++ "\n" ++ Github.filePatch file
− samples/Pulls/ListPulls.hs
@@ -1,23 +0,0 @@-module ListPulls where--import qualified Github.PullRequests as Github-import Data.List--main = do-  possiblePullRequests <- Github.pullRequestsFor "thoughtbot" "paperclip"-  case possiblePullRequests of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right pullRequests) ->-         putStrLn $ intercalate "\n\n" $ map formatPullRequest pullRequests--formatPullRequest pullRequest =-  (Github.pullRequestTitle pullRequest) ++ "\n" ++-    (take 80 $ Github.pullRequestBody pullRequest) ++ "\n" ++-    (Github.githubOwnerLogin $ Github.pullRequestUser pullRequest) ++-    " submitted to thoughtbot/paperclip " ++-    (formatGithubDate $ Github.pullRequestCreatedAt pullRequest) ++-    " updated " ++-    (formatGithubDate $ Github.pullRequestUpdatedAt pullRequest) ++ "\n" ++-    (Github.pullRequestHtmlUrl pullRequest)--formatGithubDate = show . Github.fromGithubDate
− samples/Pulls/ReviewComments/ListComments.hs
@@ -1,21 +0,0 @@-module ListComments where--import qualified Github.PullRequests.ReviewComments as Github-import Data.List--main = do-  possiblePullRequestComments <- Github.pullRequestReviewComments "thoughtbot" "factory_girl" 256-  case possiblePullRequestComments of-       (Left error)     -> putStrLn $ "Error: " ++ (show error)-       (Right comments) -> putStrLn $ intercalate "\n\n" $ map formatComment comments--formatComment :: Github.Comment -> String-formatComment comment =-  "Author: " ++ (formatAuthor $ Github.commentUser comment) ++-    "\nUpdated: " ++ (show $ Github.commentUpdatedAt comment) ++-    (maybe "" ("\nURL: "++) $ Github.commentHtmlUrl comment) ++-    "\n\n" ++ (Github.commentBody comment)--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Pulls/ReviewComments/ShowComment.hs
@@ -1,22 +0,0 @@-module ShowComments where--import qualified Github.PullRequests.ReviewComments as Github-import Data.List--main = do-  possiblePullRequestComment <- Github.pullRequestReviewComment "thoughtbot" "factory_girl" 301819-  case possiblePullRequestComment of-       (Left error)     -> putStrLn $ "Error: " ++ (show error)-       (Right comment) -> putStrLn $ formatComment comment--formatComment :: Github.Comment -> String-formatComment comment =-  "Author: " ++ (formatAuthor $ Github.commentUser comment) ++-    "\nUpdated: " ++ (show $ Github.commentUpdatedAt comment) ++-    (maybe "" ("\nURL: "++) $ Github.commentHtmlUrl comment) ++-    "\n\n" ++ (Github.commentBody comment)--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"-
− samples/Pulls/ShowCommits.hs
@@ -1,21 +0,0 @@-module ShowCommits where--import qualified Github.PullRequests as Github-import Data.List-import Data.Maybe--main = do-  possiblePullRequestCommits <- Github.pullRequestCommits "thoughtbot" "paperclip" 575-  case possiblePullRequestCommits of-       (Left error)    -> putStrLn $ "Error: " ++ (show error)-       (Right commits) -> putStrLn $ intercalate "\n" $ map formatCommit commits--formatCommit commit =-  (formatAuthor $ Github.gitCommitAuthor gitCommit) ++ "\n" ++-    (maybe "unknown SHA" id $ Github.gitCommitSha gitCommit) ++ "\n" ++-    (Github.gitCommitMessage gitCommit)-  where gitCommit = Github.commitGitCommit commit--formatAuthor :: Github.GitUser -> String-formatAuthor author =-  (Github.gitUserName author) ++ " <" ++ (Github.gitUserEmail author) ++ ">"
− samples/Pulls/ShowPull.hs
@@ -1,24 +0,0 @@-module ShowPull where--import qualified Github.PullRequests as Github-import Data.List--main = do-  possiblePullRequest <- Github.pullRequest "thoughtbot" "paperclip" 575-  case possiblePullRequest of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right pullRequest) -> putStrLn $ formatPullRequest pullRequest--formatPullRequest p =-  (Github.githubOwnerLogin $ Github.detailedPullRequestUser p) ++-    " opened this pull request " ++-    (formatGithubDate $ Github.detailedPullRequestCreatedAt p) ++ "\n" ++-    (Github.detailedPullRequestTitle p) ++ "\n" ++-    (Github.detailedPullRequestBody p) ++ "\n" ++-    (Github.detailedPullRequestState p) ++ "\n" ++-    "+" ++ (show $ Github.detailedPullRequestAdditions p) ++ " additions\n" ++-    "-" ++ (show $ Github.detailedPullRequestDeletions p) ++ " deletions\n" ++-    (show $ Github.detailedPullRequestComments p) ++ " comments\n" ++-    (Github.detailedPullRequestHtmlUrl p)--formatGithubDate = show . Github.fromGithubDate
− samples/Repos/Collaborators/IsCollaborator.hs
@@ -1,14 +0,0 @@-module IsCollaborator where--import qualified Github.Repos.Collaborators as Github-import Data.List--main = do-  let userName = "ubuwaits"-  possiblyIsCollaborator <- Github.isCollaboratorOn userName "thoughtbot" "paperclip"-  case possiblyIsCollaborator of-    (Left error) -> putStrLn $ "Error: " ++ (show error)-    (Right True) ->-      putStrLn $ userName ++ " is a collaborator on thoughtbot's paperclip"-    (Right False) ->-      putStrLn $ userName ++ " does not collaborate on thoughtbot's paperclip"
− samples/Repos/Collaborators/ListCollaborators.hs
@@ -1,15 +0,0 @@-module ListCollaborators where--import qualified Github.Repos.Collaborators as Github-import Data.List--main = do-  possibleCollaborators <- Github.collaboratorsOn "thoughtbot" "paperclip"-  case possibleCollaborators of-    (Left error) -> putStrLn $ "Error: " ++ (show error)-    (Right collaborators) ->-      putStrLn $ intercalate "\n" $ map formatAuthor collaborators--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Repos/Commits/CommitComment.hs
@@ -1,21 +0,0 @@-module CommitComment where--import qualified Github.Repos.Commits as Github-import Data.Maybe (maybe)--main = do-  possibleComment <- Github.commitCommentFor "thoughtbot" "paperclip" "669575"-  case possibleComment of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right comment) -> putStrLn $ formatComment comment--formatComment :: Github.Comment -> String-formatComment comment =-  "Author: " ++ (formatAuthor $ Github.commentUser comment) ++-    "\nUpdated: " ++ (show $ Github.commentUpdatedAt comment) ++-    (maybe "" ("\nURL: "++) $ Github.commentHtmlUrl comment) ++-    "\n\n" ++ (Github.commentBody comment)--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Repos/Commits/CommitComments.hs
@@ -1,22 +0,0 @@-module CommitComments where--import qualified Github.Repos.Commits as Github-import Data.List-import Data.Maybe (maybe)--main = do-  possibleComments <- Github.commitCommentsFor "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b"-  case possibleComments of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right comments) -> putStrLn $ intercalate "\n\n" $  map formatComment comments--formatComment :: Github.Comment -> String-formatComment comment =-  "Author: " ++ (formatAuthor $ Github.commentUser comment) ++-    "\nUpdated: " ++ (show $ Github.commentUpdatedAt comment) ++-    (maybe "" ("\nURL: "++) $ Github.commentHtmlUrl comment) ++-    "\n\n" ++ (Github.commentBody comment)--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Repos/Commits/GitDiff.hs
@@ -1,13 +0,0 @@-module GitDiff where--import qualified Github.Repos.Commits as Github-import Data.List--main = do-  possibleDiff <- Github.diff "thoughtbot" "paperclip" "41f685f6e01396936bb8cd98e7cca517e2c7d96b" "HEAD"-  either (\error -> putStrLn $ "Error: " ++ (show error))-         (putStrLn . showDiff)-         possibleDiff--showDiff diff =- intercalate "\n\n" $ map Github.filePatch $ Github.diffFiles diff
− samples/Repos/Commits/GitLog.hs
@@ -1,23 +0,0 @@-module GitLog where--import qualified Github.Repos.Commits as Github-import Data.List--main = do-  possibleCommits <- Github.commitsFor "thoughtbot" "paperclip"-  case possibleCommits of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right commits) -> putStrLn $ intercalate "\n\n" $ map formatCommit commits--formatCommit :: Github.Commit -> String-formatCommit commit =-  "commit " ++ (Github.commitSha commit) ++-    "\nAuthor: " ++ (formatAuthor author) ++-    "\nDate:   " ++ (show $ Github.fromGithubDate $ Github.gitUserDate author) ++-    "\n\n\t" ++ (Github.gitCommitMessage gitCommit)-  where author = Github.gitCommitAuthor gitCommit-        gitCommit = Github.commitGitCommit commit--formatAuthor :: Github.GitUser -> String-formatAuthor author =-  (Github.gitUserName author) ++ " <" ++ (Github.gitUserEmail author) ++ ">"
− samples/Repos/Commits/GitShow.hs
@@ -1,27 +0,0 @@-module GitShow where--import qualified Github.Repos.Commits as Github-import Data.List--main = do-  possibleCommit <- Github.commit "thoughtbot" "paperclip" "bc5c51d1ece1ee45f94b056a0f5a1674d7e8cba9"-  case possibleCommit of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right commit) -> putStrLn $ formatCommit commit--formatCommit :: Github.Commit -> String-formatCommit commit =-  "commit " ++ (Github.commitSha commit) ++-    "\nAuthor: " ++ (formatAuthor author) ++-    "\nDate:   " ++ (show $ Github.fromGithubDate $ Github.gitUserDate author) ++-    "\n\n\t" ++ (Github.gitCommitMessage gitCommit) ++ "\n" ++-    patches-  where author = Github.gitCommitAuthor gitCommit-        gitCommit = Github.commitGitCommit commit-        patches = -          intercalate "\n" $ map Github.filePatch $ Github.commitFiles commit--formatAuthor :: Github.GitUser -> String-formatAuthor author =-  (Github.gitUserName author) ++ " <" ++ (Github.gitUserEmail author) ++ ">"-
− samples/Repos/Commits/RepoComments.hs
@@ -1,22 +0,0 @@-module RepoComments where--import qualified Github.Repos.Commits as Github-import Data.List-import Data.Maybe (maybe)--main = do-  possibleComments <- Github.commentsFor "thoughtbot" "paperclip"-  case possibleComments of-    (Left error)    -> putStrLn $ "Error: " ++ (show error)-    (Right comments) -> putStrLn $ intercalate "\n\n" $  map formatComment comments--formatComment :: Github.Comment -> String-formatComment comment =-  "Author: " ++ (formatAuthor $ Github.commentUser comment) ++-    "\nUpdated: " ++ (show $ Github.commentUpdatedAt comment) ++-    (maybe "" ("\nURL: "++) $ Github.commentHtmlUrl comment) ++-    "\n\n" ++ (Github.commentBody comment)--formatAuthor :: Github.GithubOwner -> String-formatAuthor user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Repos/Forks/ListForks.hs
@@ -1,21 +0,0 @@-module ListForks where--import qualified Github.Repos.Forks as Github-import Data.List--main = do-  possibleForks <- Github.forksFor "thoughtbot" "paperclip"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n\n" . map formatFork)-                    possibleForks--formatFork fork =-  (Github.githubOwnerLogin $ Github.repoOwner fork) ++ "\t" ++-  (formatPushedAt $ Github.repoPushedAt fork) ++ "\n" ++-  (formatCloneUrl $ Github.repoCloneUrl fork)--formatPushedAt Nothing         = ""-formatPushedAt (Just pushedAt) = show $ Github.fromGithubDate pushedAt--formatCloneUrl Nothing         = ""-formatCloneUrl (Just cloneUrl) = cloneUrl
− samples/Repos/ListBranches.hs
@@ -1,11 +0,0 @@-module ListBranches where--import qualified Github.Repos as Github-import Data.List--main = do-  possibleBranches <- Github.branchesFor "thoughtbot" "paperclip"-  case possibleBranches of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right branches) ->-         putStrLn $ intercalate "\n" $ map Github.branchName branches
− samples/Repos/ListContributors.hs
@@ -1,16 +0,0 @@-module ListContributors where--import qualified Github.Repos as Github-import Data.List--main = do-  possibleContributors <- Github.contributors "thoughtbot" "paperclip"-  case possibleContributors of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right contributors) ->-         putStrLn $ intercalate "\n" $ map formatContributor contributors--formatContributor (Github.KnownContributor contributions _ login _ _ _) =-  (show $ contributions) ++ "\t" ++ login-formatContributor (Github.AnonymousContributor contributions name) =-  (show $ contributions) ++ "\t" ++ name
− samples/Repos/ListContributorsWithAnonymous.hs
@@ -1,16 +0,0 @@-module ListContributorsWithAnonymous where--import qualified Github.Repos as Github-import Data.List--main = do-  possibleContributors <- Github.contributorsWithAnonymous "thoughtbot" "paperclip"-  case possibleContributors of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right contributors) ->-         putStrLn $ intercalate "\n" $ map formatContributor contributors--formatContributor (Github.KnownContributor contributions _ login _ _ _) =-  (show $ contributions) ++ "\t" ++ login-formatContributor (Github.AnonymousContributor contributions name) =-  (show $ contributions) ++ "\t" ++ name
− samples/Repos/ListLanguages.hs
@@ -1,14 +0,0 @@-module ListLanguages where--import qualified Github.Repos as Github-import Data.List--main = do-  possibleLanguages <- Github.languagesFor "mike-burns" "ohlaunch"-  case possibleLanguages of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right languages) ->-         putStrLn $ intercalate "\n" $ map formatLanguage languages--formatLanguage (Github.Language name characterCount) =-  name ++ "\t" ++ show characterCount
− samples/Repos/ListOrgRepos.hs
@@ -1,27 +0,0 @@-module ListOrgRepos where--import qualified Github.Repos as Github-import Data.List-import Data.Maybe--main = do-  possibleRepos <- Github.organizationRepos "thoughtbot"-  case possibleRepos of-       (Left error)  -> putStrLn $ "Error: " ++ (show error)-       (Right repos) -> putStrLn $ intercalate "\n\n" $ map formatRepo repos--formatRepo repo =-  (Github.repoName repo) ++ "\t" ++-    (fromMaybe "" $ Github.repoDescription repo) ++ "\n" ++-    (Github.repoHtmlUrl repo) ++ "\n" ++-    (fromMaybe "" $ Github.repoCloneUrl repo) ++ "\t" ++-    (formatDate $ Github.repoUpdatedAt repo) ++ "\n" ++-    formatLanguage (Github.repoLanguage repo) ++-    "watchers: " ++ (show $ Github.repoWatchers repo) ++ "\t" ++-    "forks: " ++ (show $ Github.repoForks repo)--formatDate (Just date) = show . Github.fromGithubDate $ date-formatDate Nothing = "????"--formatLanguage (Just language) = "language: " ++ language ++ "\t"-formatLanguage Nothing = ""
− samples/Repos/ListTags.hs
@@ -1,11 +0,0 @@-module ListTags where--import qualified Github.Repos as Github-import Data.List--main = do-  possibleTags <- Github.tagsFor "thoughtbot" "paperclip"-  case possibleTags of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right tags) ->-         putStrLn $ intercalate "\n" $ map Github.tagName tags
− samples/Repos/ListUserRepos.hs
@@ -1,27 +0,0 @@-module ListUserRepos where--import qualified Github.Repos as Github-import Data.List-import Data.Maybe--main = do-  possibleRepos <- Github.userRepos "mike-burns" Github.Owner-  case possibleRepos of-       (Left error)  -> putStrLn $ "Error: " ++ (show error)-       (Right repos) -> putStrLn $ intercalate "\n\n" $ map formatRepo repos--formatRepo repo =-  (Github.repoName repo) ++ "\t" ++-    (fromMaybe "" $ Github.repoDescription repo) ++ "\n" ++-    (Github.repoHtmlUrl repo) ++ "\n" ++-    (fromMaybe "" $ Github.repoCloneUrl repo) ++ "\t" ++-    (formatDate $ Github.repoUpdatedAt repo) ++ "\n" ++-    formatLanguage (Github.repoLanguage repo) ++-    "watchers: " ++ (show $ Github.repoWatchers repo) ++ "\t" ++-    "forks: " ++ (show $ Github.repoForks repo)--formatDate (Just date) = show . Github.fromGithubDate $ date-formatDate Nothing = ""--formatLanguage (Just language) = "language: " ++ language ++ "\t"-formatLanguage Nothing = ""
− samples/Repos/ShowRepo.hs
@@ -1,26 +0,0 @@-module ShowRepo where--import qualified Github.Repos as Github-import Data.List-import Data.Maybe--main = do-  possibleRepo <- Github.userRepo "mike-burns" "trylambda"-  case possibleRepo of-       (Left error) -> putStrLn $ "Error: " ++ (show error)-       (Right repo) -> putStrLn $ formatRepo repo--formatRepo repo =-  (Github.repoName repo) ++ "\t" ++-    (fromMaybe "" $ Github.repoDescription repo) ++ "\n" ++-    (Github.repoHtmlUrl repo) ++ "\n" ++-    (Github.repoCloneUrl repo) ++ "\t" ++-    (formatDate $ Github.repoUpdatedAt repo) ++ "\n" ++-    formatLanguage (Github.repoLanguage repo) ++-    "watchers: " ++ (show $ Github.repoWatchers repo) ++ "\t" ++-    "forks: " ++ (show $ Github.repoForks repo)--formatDate = show . Github.fromGithubDate--formatLanguage (Just language) = "language: " ++ language ++ "\t"-formatLanguage Nothing = ""
− samples/Repos/Starring/ListStarred.hs
@@ -1,25 +0,0 @@-module ListStarred where--import qualified Github.Repos.Starring as Github-import Data.List (intercalate)-import Data.Maybe (fromMaybe)--main = do-  possibleRepos <- Github.reposStarredBy Nothing "mike-burns"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n\n" . map formatRepo)-                    possibleRepos--formatRepo repo =-  (Github.repoName repo) ++ "\t" ++-    (fromMaybe "" $ Github.repoDescription repo) ++ "\n" ++-    (Github.repoHtmlUrl repo) ++ "\n" ++-    (fromMaybe "" $ Github.repoCloneUrl repo) ++ "\t" ++-    (formatDate $ Github.repoUpdatedAt repo) ++ "\n" ++-    formatLanguage (Github.repoLanguage repo)--formatDate (Just date) = show . Github.fromGithubDate $ date-formatDate Nothing = ""--formatLanguage (Just language) = "language: " ++ language ++ "\t"-formatLanguage Nothing = ""
− samples/Repos/Watching/ListWatched.hs
@@ -1,27 +0,0 @@-module ListWatched where--import qualified Github.Repos.Watching as Github-import Data.List (intercalate)-import Data.Maybe (fromMaybe)--main = do-  possibleRepos <- Github.reposWatchedBy "mike-burns"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n\n" . map formatRepo)-                    possibleRepos--formatRepo repo =-  (Github.repoName repo) ++ "\t" ++-    (fromMaybe "" $ Github.repoDescription repo) ++ "\n" ++-    (Github.repoHtmlUrl repo) ++ "\n" ++-    (fromMaybe "" $ Github.repoCloneUrl repo) ++ "\t" ++-    (formatDate $ Github.repoUpdatedAt repo) ++ "\n" ++-    formatLanguage (Github.repoLanguage repo) ++-    "watchers: " ++ (show $ Github.repoWatchers repo) ++ "\t" ++-    "forks: " ++ (show $ Github.repoForks repo)--formatDate (Just date) = show . Github.fromGithubDate $ date-formatDate Nothing = ""--formatLanguage (Just language) = "language: " ++ language ++ "\t"-formatLanguage Nothing = ""
− samples/Repos/Watching/ListWatchers.hs
@@ -1,14 +0,0 @@-module ListWatchers where--import qualified Github.Repos.Watching as Github-import Data.List (intercalate)--main = do-  possibleWatchers <- Github.watchersFor "doubledrones" "git-annex"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n" . map formatWatcher)-                    possibleWatchers--formatWatcher :: Github.GithubOwner -> String-formatWatcher user =-  (Github.githubOwnerLogin user) ++ " (" ++ (Github.githubOwnerUrl user) ++ ")"
− samples/Repos/Webhooks/CreateWebhook.hs
@@ -1,24 +0,0 @@-module CreateWebhook where--import Github.Repos.Webhooks-import qualified Github.Auth as Auth-import Github.Data.Definitions-import qualified Data.Map as M--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  let config = M.fromList [("url", "https://foo3.io"), ("content_type", "application/json"), ("insecure_ssl", "1")]-  let webhookDef = NewRepoWebhook {-        newRepoWebhookName = "web",-        newRepoWebhookConfig = config,-        newRepoWebhookEvents = Just [WebhookWildcardEvent],-        newRepoWebhookActive = Just True-      }-  newWebhook <- createRepoWebhook' auth "repoOwner" "repoName" webhookDef-  case newWebhook of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right webhook) -> putStrLn $ formatRepoWebhook webhook--formatRepoWebhook :: RepoWebhook -> String-formatRepoWebhook (RepoWebhook _ _ _ name _ _ _ _ _ _) = show name
− samples/Repos/Webhooks/DeleteWebhook.hs
@@ -1,12 +0,0 @@-module DeleteWebhook where--import Github.Repos.Webhooks-import qualified Github.Auth as Auth--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  resp <- deleteRepoWebhook' auth "repoOwner" "repoName" 123-  case resp of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right stat) -> putStrLn $ "Resp: " ++ (show stat)
− samples/Repos/Webhooks/EditWebhook.hs
@@ -1,23 +0,0 @@-module EditWebhook where--import Github.Repos.Webhooks-import qualified Github.Auth as Auth-import Github.Data.Definitions--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  let editWebhookDef = EditRepoWebhook {-        editRepoWebhookRemoveEvents = Just [WebhookWildcardEvent],-        editRepoWebhookAddEvents = Just [WebhookCommitCommentEvent, WebhookGollumEvent],-        editRepoWebhookConfig = Nothing,-        editRepoWebhookEvents = Nothing,-        editRepoWebhookActive = Just True-      }-  newWebhook <- editRepoWebhook' auth "repoOwner" "repoName" 123 editWebhookDef-  case newWebhook of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right webhook) -> putStrLn $ formatRepoWebhook webhook--formatRepoWebhook :: RepoWebhook -> String-formatRepoWebhook (RepoWebhook _ _ _ name _ _ _ _ _ _) = show name
− samples/Repos/Webhooks/ListWebhook.hs
@@ -1,16 +0,0 @@-module ListWebhook where--import qualified Github.Repos.Webhooks as W-import qualified Github.Auth as Auth-import qualified Github.Data.Definitions as Def--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  possibleWebhook <- W.webhookFor' auth "repoOwner" "repoName" 123-  case possibleWebhook of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right webhook) -> putStrLn $ formatRepoWebhook webhook--formatRepoWebhook :: Def.RepoWebhook -> String-formatRepoWebhook (Def.RepoWebhook _ _ _ name _ _ _ _ _ _) = show name
− samples/Repos/Webhooks/ListWebhooks.hs
@@ -1,17 +0,0 @@-module ListWebhooks where--import qualified Github.Repos.Webhooks as W-import qualified Github.Auth as Auth-import qualified Github.Data.Definitions as Def-import Data.List--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  possibleWebhooks <- W.webhooksFor' auth "repoOwner" "repoName"-  case possibleWebhooks of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right webhooks) -> putStrLn $ intercalate "\n" $ map formatRepoWebhook webhooks--formatRepoWebhook :: Def.RepoWebhook -> String-formatRepoWebhook (Def.RepoWebhook _ _ _ name _ _ _ _ _ _) = show name
− samples/Repos/Webhooks/PingWebhook.hs
@@ -1,12 +0,0 @@-module PingWebhook where--import Github.Repos.Webhooks-import qualified Github.Auth as Auth--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  resp <- pingRepoWebhook' auth "repoOwner" "repoName" 123-  case resp of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right stat) -> putStrLn $ "Resp: " ++ (show stat)
− samples/Repos/Webhooks/TestPushWebhook.hs
@@ -1,12 +0,0 @@-module TestPushWebhook where--import Github.Repos.Webhooks-import qualified Github.Auth as Auth--main :: IO ()-main = do-  let auth = Auth.GithubOAuth "oauthtoken"-  resp <- testPushRepoWebhook' auth "repoOwner" "repoName" 123-  case resp of-    (Left err) -> putStrLn $ "Error: " ++ (show err)-    (Right stat) -> putStrLn $ "Resp: " ++ (show stat)
− samples/Search/SearchRepos.hs
@@ -1,56 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-module SearchRepos where--import qualified Github.Search as Github-import qualified Github.Data as Github-import Control.Monad (forM,forM_)-import Data.Maybe (fromMaybe)-import Data.List (intercalate)-import System.Environment (getArgs)-import Text.Printf (printf)-import Data.Time.Clock (getCurrentTime, UTCTime(..))-import Data.Time.LocalTime (utc,utcToLocalTime,localDay,localTimeOfDay,TimeOfDay(..))-import Data.Time.Calendar (toGregorian)--main = do-  args <- getArgs-  date <- case args of-            (x:_)     -> return x-            otherwise -> today-  let query = "q=language%3Ahaskell created%3A>" ++ date ++ "&per_page=100"-  let auth = Nothing-  result <- Github.searchRepos' auth query-  case result of-    Left e  -> putStrLn $ "Error: " ++ show e-    Right r -> do forM_ (Github.searchReposRepos r) (\r -> do-                    putStrLn $ formatRepo r-                    putStrLn ""-                    )-                  putStrLn $ "Count: " ++ show n ++ " Haskell repos created since " ++ date-      where n = Github.searchReposTotalCount r---- | return today (in UTC) formatted as YYYY-MM-DD-today :: IO String-today = do-  now <- getCurrentTime-  let day = localDay $ utcToLocalTime utc now-      (y,m,d) = toGregorian day-   in return $ printf "%d-%02d-%02d" y m d--formatRepo :: Github.Repo -> String-formatRepo r =-  let fields = [ ("Name", Github.repoName)-                 ,("URL",  Github.repoHtmlUrl)-                 ,("Description", orEmpty . Github.repoDescription)-                 ,("Created-At", formatMaybeDate . Github.repoCreatedAt)-                 ,("Pushed-At", formatMaybeDate . Github.repoPushedAt)-               ]-  in intercalate "\n" $ map fmt fields-    where fmt (s,f) = fill 12 (s ++ ":") ++ " " ++ f r-          orEmpty = fromMaybe ""-          fill n s = s ++ replicate n' ' '-            where n' = max 0 (n - length s) --formatMaybeDate = maybe "???" formatDate--formatDate = show . Github.fromGithubDate
− samples/Users/Followers/ListFollowers.hs
@@ -1,12 +0,0 @@-module ListFollowers where--import qualified Github.Users.Followers as Github-import Data.List (intercalate)--main = do-  possibleUsers <- Github.usersFollowing "mike-burns"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n" . map formatUser)-                    possibleUsers--formatUser = Github.githubOwnerLogin
− samples/Users/Followers/ListFollowing.hs
@@ -1,13 +0,0 @@-module ListFollowing where--import qualified Github.Users.Followers as Github-import Data.List (intercalate)--main = do-  possibleUsers <- Github.usersFollowedBy "mike-burns"-  putStrLn $ either (("Error: "++) . show)-                    (intercalate "\n" . map formatUser)-                    possibleUsers--formatUser = Github.githubOwnerLogin-
− samples/Users/ShowUser.hs
@@ -1,52 +0,0 @@-module ShowUser where--import qualified Github.Users as Github-import Data.Maybe (fromMaybe)--main = do-  possibleUser <- Github.userInfoFor "mike-burns"-  putStrLn $ either (("Error: "++) . show) formatUser possibleUser--formatUser user@(Github.DetailedOrganization {}) =-  "Organization: " ++ (formatName userName login) ++ "\t" ++-    (fromMaybe "" company) ++ "\t" ++-    (fromMaybe "" location) ++ "\n" ++-    (fromMaybe "" blog) ++ "\t" ++ "\n" ++-    htmlUrl ++ "\t" ++ (formatDate createdAt) ++ "\n\n" ++-    (fromMaybe "" bio)-  where-    userName = Github.detailedOwnerName user-    login = Github.detailedOwnerLogin user-    company = Github.detailedOwnerCompany user-    location = Github.detailedOwnerLocation user-    blog = Github.detailedOwnerBlog user-    htmlUrl = Github.detailedOwnerHtmlUrl user-    createdAt = Github.detailedOwnerCreatedAt user-    bio = Github.detailedOwnerBio user--formatUser user@(Github.DetailedUser {}) =-  (formatName userName login) ++ "\t" ++ (fromMaybe "" company) ++ "\t" ++-    (fromMaybe "" location) ++ "\n" ++-    (fromMaybe "" blog) ++ "\t" ++ "<" ++ (fromMaybe "" email) ++ ">" ++ "\n" ++-    htmlUrl ++ "\t" ++ (formatDate createdAt) ++ "\n" ++-    "hireable: " ++ (formatHireable (fromMaybe False isHireable)) ++ "\n\n" ++-    (fromMaybe "" bio)-  where-    userName = Github.detailedOwnerName user-    login = Github.detailedOwnerLogin user-    company = Github.detailedOwnerCompany user-    location = Github.detailedOwnerLocation user-    blog = Github.detailedOwnerBlog user-    email = Github.detailedOwnerEmail user -    htmlUrl = Github.detailedOwnerHtmlUrl user-    createdAt = Github.detailedOwnerCreatedAt user-    isHireable = Github.detailedOwnerHireable user-    bio = Github.detailedOwnerBio user--formatName Nothing login = login-formatName (Just name) login = name ++ "(" ++ login ++ ")"--formatHireable True = "yes"-formatHireable False = "no"--formatDate = show . Github.fromGithubDate
+ 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
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.ActivitySpec where++import qualified GitHub++import GitHub.Auth                        (Auth (..))+import GitHub.Endpoints.Activity.Starring (myStarredAcceptStarR)+import GitHub.Endpoints.Activity.Watching (watchersForR)+import GitHub.Request                     (executeRequest)++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 "watchersForR" $ do+    it "works" $ withAuth $ \auth -> do+      cs <- executeRequest auth $ watchersForR "haskell-github" "github" GitHub.FetchAll+      cs `shouldSatisfy` isRight+      V.length (fromRightS cs) `shouldSatisfy` (> 10)+  describe "myStarredR" $ do+      it "works" $ withAuth $ \auth -> do+          cs <- executeRequest auth $ myStarredAcceptStarR (GitHub.FetchAtLeast 31)+          cs `shouldSatisfy` isRight+          fromRightS cs `shouldSatisfy` (\xs -> V.length xs > 30)
+ spec/GitHub/CommitsSpec.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.CommitsSpec where++import GitHub.Auth                    (Auth (..))+import GitHub.Endpoints.Repos.Commits (commitSha, commitsForR, diffR, mkCommitName, FetchCount (..))+import GitHub.Request                 (github)++import Control.Monad      (forM_)+import Data.Either.Compat (isRight)+import Data.List          (nub, sort)+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, pendingWith, shouldBe,+                           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 "commitsFor" $ do+    it "works" $ withAuth $ \auth -> do+      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 <- github auth commitsForR "haskell-github" "github" (FetchAtLeast 40)+      cs `shouldSatisfy` isRight+      let cs' = fromRightS cs+      V.length cs' `shouldSatisfy` (< 70)+      let hashes = sort $ map commitSha $ V.toList cs'+      hashes `shouldBe` nub hashes++  describe "diff" $ do+    it "works" $ withAuth $ \auth -> do+      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 <- github auth diffR "haskell-github" "github" (commitSha a) (commitSha b)+        d `shouldSatisfy` isRight++    it "issue #155" $ withAuth $ \auth -> do+      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
@@ -0,0 +1,36 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.EventsSpec where++import Data.Either        (isRight)+import Data.String        (fromString)+import Prelude ()+import Prelude.Compat+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, shouldSatisfy,+                           pendingWith)++import qualified GitHub+import GitHub.Data (Auth(..))++fromRightS :: Show a => Either a b -> b+fromRightS (Left xs) = error $ "Should be Right" ++ show xs+fromRightS (Right xs) = xs++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 "repositoryEventsR" $ do+    it "returns non empty list of events" $ shouldSucceed $+      GitHub.repositoryEventsR "haskell-github" "github" 1+  describe "userEventsR" $ do+    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+          length (fromRightS cs) `shouldSatisfy` (> 1)
+ spec/GitHub/IssuesSpec.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.IssuesSpec where++import qualified GitHub++import Prelude ()+import Prelude.Compat++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++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 = do+    describe "issuesForRepoR" $ do+        it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do+            cs <- GitHub.executeRequest auth $+                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")+      , ("haskell-github", "github")+      ]
+ spec/GitHub/OrganizationsSpec.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.OrganizationsSpec where++import GitHub                                 (FetchCount (..), github)+import GitHub.Auth                            (Auth (..))+import GitHub.Data+       (SimpleOrganization (..), SimpleOwner (..), SimpleTeam (..))+import GitHub.Endpoints.Organizations         (publicOrganizationsForR)+import GitHub.Endpoints.Organizations.Members (membersOfR)++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)++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 "publicOrganizationsFor'" $ do+    it "decodes simple organization json" $ do+      let orgs = eitherDecodeStrict $(embedFile "fixtures/user-organizations.json")+      simpleOrganizationLogin (head $ fromRightS orgs) `shouldBe` "github"++    it "returns information about the user's organizations" $ withAuth $ \auth -> do+      orgs <- github auth publicOrganizationsForR "mike-burns" FetchAll+      orgs  `shouldSatisfy` isRight++  describe "teamsOf" $ do+    it "parse" $ do+      let ts = eitherDecodeStrict $(embedFile "fixtures/list-teams.json")+      simpleTeamName (head $ fromRightS ts) `shouldBe` "Justice League"++  describe "membersOf" $ do+    it "parse" $ do+      let ms = eitherDecodeStrict $(embedFile "fixtures/members-list.json")+      simpleOwnerLogin (head $ fromRightS ms) `shouldBe` "octocat"++    it "works" $ withAuth $ \auth -> do+      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
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.PullRequestReviewsSpec where++import qualified GitHub+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)++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 = do+    describe "pullRequestReviewsR" $ do+        it "works" $ withAuth $ \auth -> for_ prs $ \(owner, repo, prid) -> do+            cs <- GitHub.executeRequest auth $+                GitHub.pullRequestReviewsR owner repo prid GitHub.FetchAll+            cs `shouldSatisfy` isRight+  where+    prs =+      [("haskell-github", "github", IssueNumber 268)]
+ spec/GitHub/PullRequestsSpec.hs view
@@ -0,0 +1,164 @@+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE TemplateHaskell       #-}+module GitHub.PullRequestsSpec where++import qualified GitHub as GH++import Prelude ()+import Prelude.Compat++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 :: (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 "pullRequestsForR" $ do+        it "works" $ withAuth $ \auth -> for_ repos $ \(owner, repo) -> do+            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 (GH.simplePullRequestRequestedReviewers simplePullRequestOpened)+                `shouldBe` 0++            V.length (GH.pullRequestRequestedReviewers pullRequestOpened)+                `shouldBe` 0++        it "decodes a pull request 'review_requested' payload" $ do+            V.length (GH.simplePullRequestRequestedReviewers simplePullRequestReviewRequested)+                `shouldBe` 1++            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 <- 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")+      , ("haskell-github", "github")+      ]+    opts = GH.stateClosed++    simplePullRequestOpened :: GH.SimplePullRequest+    simplePullRequestOpened =+        fromRightS (eitherDecodeStrict prOpenedPayload)++    pullRequestOpened :: GH.PullRequest+    pullRequestOpened =+        fromRightS (eitherDecodeStrict prOpenedPayload)++    simplePullRequestReviewRequested :: GH.SimplePullRequest+    simplePullRequestReviewRequested =+        fromRightS (eitherDecodeStrict prReviewRequestedPayload)++    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
@@ -0,0 +1,53 @@+{-# LANGUAGE OverloadedStrings #-}+module GitHub.ReleasesSpec where++import qualified GitHub++import GitHub.Auth                     (Auth (..))+import GitHub.Endpoints.Repos.Releases+       (Release (..), latestReleaseR, releaseByTagNameR, releaseR, releasesR)+import GitHub.Request                  (executeRequest)++import Data.Either.Compat (isRight)+import Data.Proxy         (Proxy (..))+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec+       (Spec, describe, it, pendingWith, shouldBe, 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+  let v154Id   = GitHub.mkId (Proxy :: Proxy Release) 5254449+      v154Text = "v1.5.4"+  describe "releasesR" $ do+    it "works" $ withAuth $ \auth -> do+      rs <- executeRequest auth $ releasesR "calleerlandsson" "pick" GitHub.FetchAll+      rs `shouldSatisfy` isRight+      V.length (fromRightS rs) `shouldSatisfy` (> 14)+  describe "releaseR" $ do+    it "works" $ withAuth $ \auth -> do+      rs <- executeRequest auth $ releaseR "calleerlandsson" "pick" v154Id+      rs `shouldSatisfy` isRight+      releaseTagName (fromRightS rs)`shouldBe` v154Text+  describe "latestReleaseR" $ do+    it "works" $ withAuth $ \auth -> do+      rs <- executeRequest auth $ latestReleaseR "calleerlandsson" "pick"+      rs `shouldSatisfy` isRight+  describe "releaseByTagNameR" $ do+    it "works" $ withAuth $ \auth -> do+      rs <- executeRequest auth $ releaseByTagNameR "calleerlandsson" "pick" v154Text+      rs `shouldSatisfy` isRight+      releaseId (fromRightS rs)`shouldBe` v154Id
+ spec/GitHub/ReposSpec.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}++#if __GLASGOW_HASKELL__ >= 900+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}+#endif++module GitHub.ReposSpec where++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 qualified Data.HashMap.Strict as HM++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 "repositoryR" $ do+    it "works" $ withAuth $ \auth -> do+      er <- github auth repositoryR "haskell-github" "github"+      er `shouldSatisfy` isRight+      let Right r = er+      -- https://github.com/haskell-github/github/pull/219+      repoDefaultBranch r `shouldBe` Just "master"++  describe "currentUserRepos" $ do+    it "works" $ withAuth $ \auth -> do+      cs <- github auth currentUserReposR RepoPublicityAll FetchAll+      cs `shouldSatisfy` isRight++  describe "userRepos" $ do+    it "works" $ withAuth $ \auth -> do+      cs <- github auth userReposR "phadej" RepoPublicityAll FetchAll+      cs `shouldSatisfy` isRight++  describe "languagesFor'" $ do+    it "works" $ withAuth $ \auth -> do+      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
@@ -0,0 +1,67 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.SearchSpec where++import Prelude ()+import Prelude.Compat++import Data.Aeson         (eitherDecodeStrict)+import Data.FileEmbed     (embedFile)+import Data.Proxy         (Proxy (..))+import Data.String        (fromString)+import System.Environment (lookupEnv)+import Test.Hspec         (Spec, describe, it, pendingWith, shouldBe)++import qualified Data.Vector as V++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+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 "searchIssues" $ do+    it "decodes issue search response JSON" $ do+      let searchIssuesResult = fromRightS $ eitherDecodeStrict $(embedFile "fixtures/issue-search.json") :: SearchResult Issue+      searchResultTotalCount searchIssuesResult `shouldBe` 2++      let issues = searchResultResults searchIssuesResult+      V.length issues `shouldBe` 2++      let issue1 = issues V.! 0+      issueId issue1 `shouldBe` mkId (Proxy :: Proxy Issue) 123898390+      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` 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: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
@@ -0,0 +1,82 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+module GitHub.UsersSpec where++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 qualified GitHub++import GitHub.Data+       (Auth (..), Organization (..), User (..), fromOwner)+import GitHub.Endpoints.Users+       (ownerInfoForR, userInfoCurrentR, userInfoForR)+import GitHub.Endpoints.Users.Followers (usersFollowedByR, usersFollowingR)+import GitHub.Request                   (github)++fromRightS :: Show a => Either a b -> b+fromRightS (Right b) = b+fromRightS (Left a) = error $ "Expected a Right and got a Left" ++ show a++fromLeftS :: Show b => Either a b -> a+fromLeftS (Left b) = b+fromLeftS (Right a) = error $ "Expected a Left and got a RIght" ++ 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 "userInfoFor" $ do+    it "decodes user json" $ do+      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 <- github auth userInfoForR "mike-burns"+      userLogin (fromRightS userInfo) `shouldBe` "mike-burns"++    it "catches http exceptions" $ withAuth $ \auth -> do+      userInfo <- github auth userInfoForR "i-hope-this-user-will-never-exist"+      userInfo `shouldSatisfy` isLeft++    it "should fail for organization" $ withAuth $ \auth -> do+      userInfo <- github auth userInfoForR "haskell"+      userInfo `shouldSatisfy` isLeft++  describe "ownerInfoFor" $ do+    it "works for users and organizations" $ withAuth $ \auth -> do+      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 "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 <- github auth usersFollowingR "phadej" (GitHub.FetchAtLeast 10)+      us `shouldSatisfy` isRight++  describe "usersFollowedBy" $ do+    it "works" $ withAuth $ \auth -> do+      us <- github auth usersFollowedByR "phadej" (GitHub.FetchAtLeast 10)+      us `shouldSatisfy` isRight
+ src/GitHub.hs view
@@ -0,0 +1,546 @@+-- |+-- This module re-exports all request constructors and data definitions from+-- this package.+--+-- 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/>+    repositoryEventsR,+    userEventsR,++    -- ** Notifications+    -- | See <https://developer.github.com/v3/activity/notifications/>+    getNotificationsR,+    markNotificationAsReadR,+    markAllNotificationsAsReadR,++    -- ** Starring+    -- | See <https://developer.github.com/v3/activity/starring/>+    --+    -- Missing endpoints:+    --+    -- * Check if you are starring a repository+    stargazersForR,+    reposStarredByR,+    myStarredR,+    myStarredAcceptStarR,+    starRepoR,+    unstarRepoR,++    -- ** Watching+    -- | See <https://developer.github.com/v3/activity/>+    --+    -- Missing endpoints:+    --+    -- * Query a Repository Subscription+    -- * Set a Repository Subscription+    watchersForR,+    reposWatchedByR,+    unwatchRepoR,++    -- * Gists+    -- | See <https://developer.github.com/v3/gists/>+    --+    -- Missing endpoints:+    --+    -- * Query a specific revision of a gist+    -- * Edit a gist+    -- * List gist commits+    -- * Check if a gist is starred+    -- * Fork a gist+    -- * List gist forks+    gistsR,+    gistR,+    createGistR,+    starGistR,+    unstarGistR,+    deleteGistR,++    -- ** Comments+    -- | See <https://developer.github.com/v3/gists/comments/>+    --+    -- Missing endpoints:+    -- * Create a comment+    -- * Edit a comment+    -- * Delete a comment+    commentsOnR,+    gistCommentR,++    -- * Git Data+    -- | See <https://developer.github.com/v3/git/>++    -- ** Blobs+    -- | See <https://developer.github.com/v3/git/blobs/>+    blobR,++    -- ** Commits+    -- | See <https://developer.github.com/v3/git/commits/>+    gitCommitR,++    -- ** References+    -- | See <https://developer.github.com/v3/git/refs/>+    referenceR,+    referencesR,+    createReferenceR,+    deleteReferenceR,+    namespacedReferencesR,++    -- ** Trees+    -- | See <https://developer.github.com/v3/git/trees/>+    treeR,+    nestedTreeR,++    -- * Issues+    -- | See <https://developer.github.com/v3/issues/>+    --+    currentUserIssuesR,+    organizationIssuesR,+    issueR,+    issuesForRepoR,+    createIssueR,+    editIssueR,++    -- ** Comments+    -- | See <https://developer.github.com/v3/issues/comments/>+    --+    commentR,+    commentsR,+    createCommentR,+    deleteCommentR,+    editCommentR,++    -- ** Events+    -- | See <https://developer.github.com/v3/issues/events/>+    --+    eventsForIssueR,+    eventsForRepoR,+    eventR,++    -- ** Labels+    -- | See <https://developer.github.com/v3/issues/labels/>+    --+    labelsOnRepoR,+    labelR,+    createLabelR,+    updateLabelR,+    deleteLabelR,+    labelsOnIssueR,+    addLabelsToIssueR,+    removeLabelFromIssueR,+    replaceAllLabelsForIssueR,+    removeAllLabelsFromIssueR,+    labelsOnMilestoneR,++    -- ** Milestone+    -- | See <https://developer.github.com/v3/issues/milestones/>+    --+    milestonesR,+    milestoneR,+    createMilestoneR,+    updateMilestoneR,+    deleteMilestoneR,++    -- * Organizations+    -- | See <https://developer.github.com/v3/orgs/>+    --+    -- Missing endpoints:+    --+    -- * List your organizations+    -- * List all organizations+    -- * Edit an organization+    publicOrganizationsForR,+    publicOrganizationR,+    organizationsR,+    -- ** Members+    -- | See <https://developer.github.com/v3/orgs/members/>+    --+    -- Missing endpoints: All except /Members List/ and /Check Membership/+    membersOfR,+    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/>+    --+    -- Missing endpoints:+    --+    -- * Query team member (deprecated)+    -- * Add team member (deprecated)+    -- * Remove team member (deprecated)+    -- * Check if a team manages a repository+    -- * Add team repository+    -- * Remove team repository+    teamsOfR,+    teamInfoForR,+    createTeamForR,+    editTeamR,+    deleteTeamR,+    listTeamMembersR,+    listTeamReposR,+    teamMembershipInfoForR,+    addTeamMembershipForR,+    deleteTeamMembershipForR,+    listTeamsCurrentR,++    -- * Pull Requests+    -- | See <https://developer.github.com/v3/pulls/>+    pullRequestsForR,+    pullRequestR,+    pullRequestPatchR,+    pullRequestDiffR,+    createPullRequestR,+    updatePullRequestR,+    pullRequestCommitsR,+    pullRequestFilesR,+    isPullRequestMergedR,+    mergePullRequestR,++    -- ** Review comments+    -- | See <https://developer.github.com/v3/pulls/comments/>+    --+    -- Missing endpoints:+    --+    -- * List comments in a repository+    -- * Edit a comment+    -- * Delete a comment+    pullRequestCommentsR,+    pullRequestCommentR,+    createPullCommentR,+    createPullCommentReplyR,++    -- ** Pull request reviews+    -- | See <https://developer.github.com/v3/pulls/reviews/>+    --+    -- Missing endpoints:+    --+    -- * Delete a pending review+    -- * Create a pull request review+    -- * Submit a pull request review+    -- * Dismiss a pull request review+    pullRequestReviewsR,+    pullRequestReviewR,+    pullRequestReviewCommentsR,++    -- * Repositories+    -- | See <https://developer.github.com/v3/repos/>+    --+    -- Missing endpoints:+    --+    -- * List all public repositories+    -- * List Teams+    -- * Query Branch+    -- * Enabling and disabling branch protection+    currentUserReposR,+    userReposR,+    organizationReposR,+    repositoryR,+    contributorsR,+    languagesForR,+    tagsForR,+    branchesForR,++    -- ** Collaborators+    -- | See <https://developer.github.com/v3/repos/collaborators/>+    collaboratorsOnR,+    collaboratorPermissionOnR,+    isCollaboratorOnR,+    addCollaboratorR,++    -- ** Comments+    -- | See <https://developer.github.com/v3/repos/comments/>+    --+    -- Missing endpoints:+    --+    -- * Create a commit comment+    -- * Update a commit comment+    -- * Delete a commit comment+    commentsForR,+    commitCommentsForR,+    commitCommentForR,++    -- ** Commits+    -- | See <https://developer.github.com/v3/repos/commits/>+    commitsForR,+    commitsWithOptionsForR,+    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/>+    --+    -- Missing endpoints:+    --+    -- * 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,+    webhookForR,+    createRepoWebhookR,+    editRepoWebhookR,+    testPushRepoWebhookR,+    pingRepoWebhookR,+    deleteRepoWebhookR,++    -- * Releases+    releasesR,+    releaseR,+    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/>+    searchReposR,+    searchCodeR,+    searchIssuesR,+    searchUsersR,++    -- * Users+    -- | See <https://developer.github.com/v3/users/>+    --+    -- Missing endpoints:+    --+    -- * Update the authenticated user+    -- * Query all users+    userInfoForR,+    ownerInfoForR,+    userInfoCurrentR,++    -- ** Emails+    -- | See <https://developer.github.com/v3/users/emails/>+    --+    -- Missing endpoints:+    --+    -- * Add email address(es)+    -- * Delete email address(es)+    -- * Toggle primary email visibility+    currentUserEmailsR,+    currentUserPublicEmailsR,++    -- ** Followers+    -- | See <https://developer.github.com/v3/users/followers/>+    --+    -- Missing endpoints:+    --+    -- * Check if you are following a user+    -- * Check if one user follows another+    -- * Follow a user+    -- * Unfollow a user+    usersFollowingR,+    usersFollowedByR,++    -- ** 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+    module GitHub.Request,+    ) 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+import GitHub.Endpoints.Gists.Comments+import GitHub.Endpoints.GitData.Blobs+import GitHub.Endpoints.GitData.Commits+import GitHub.Endpoints.GitData.References+import GitHub.Endpoints.GitData.Trees+import GitHub.Endpoints.Issues+import GitHub.Endpoints.Issues.Comments+import GitHub.Endpoints.Issues.Events+import GitHub.Endpoints.Issues.Labels+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.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+import GitHub.Endpoints.Search+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
@@ -0,0 +1,58 @@+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.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  -- ^ 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+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
@@ -0,0 +1,155 @@+-- |+-- This module re-exports the @GitHub.Data.@ and "GitHub.Auth" submodules.++module GitHub.Data (+    -- * Tagged types+    -- ** Name+    Name,+    mkName,+    untagName,+    mkOwnerName,+    mkUserName,+    mkTeamName,+    mkOrganizationName,+    mkRepoName,+    mkCommitName,+    fromUserName,+    fromOrganizationName,+    -- ** Id+    Id,+    mkId,+    untagId,+    mkOwnerId,+    mkUserId,+    mkTeamId,+    mkOrganizationId,+    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,+    module GitHub.Data.GitData,+    module GitHub.Data.Invitation,+    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,+    module GitHub.Data.Search,+    module GitHub.Data.Statuses,+    module GitHub.Data.Teams,+    module GitHub.Data.URL,+    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+import GitHub.Data.GitData+import GitHub.Data.Id+import GitHub.Data.Invitation+import GitHub.Data.Issues+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+import GitHub.Data.Search+import GitHub.Data.Statuses+import GitHub.Data.Teams+import GitHub.Data.URL+import GitHub.Data.Webhooks+import GitHub.Data.Webhooks.Validate++mkOwnerId :: Int -> Id Owner+mkOwnerId = Id++mkOwnerName :: Text -> Name Owner+mkOwnerName = N++mkUserId :: Int -> Id User+mkUserId = Id++mkUserName :: Text -> Name User+mkUserName = N++mkTeamId :: Int -> Id Team+mkTeamId = Id++mkTeamName :: Text -> Name Team+mkTeamName = N++mkOrganizationId :: Int -> Id Organization+mkOrganizationId = Id++mkOrganizationName :: Text -> Name Organization+mkOrganizationName = N++mkRepoId :: Int -> Id Repo+mkRepoId = Id++mkRepoName :: Text -> Name Repo+mkRepoName = N++mkCommitName :: Text -> Name Commit+mkCommitName = N++fromOrganizationName :: Name Organization -> Name Owner+fromOrganizationName = N . untagName++fromUserName :: Name User -> Name Owner+fromUserName = N . untagName++fromOrganizationId :: Id Organization -> Id Owner+fromOrganizationId = Id . untagId++fromUserId :: Id User -> Id Owner+fromUserId = Id . untagId
+ 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
@@ -0,0 +1,114 @@+module GitHub.Data.Activities where++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, Eq, Ord, Generic)++instance NFData RepoStarred+instance Binary RepoStarred++-- JSON Instances+instance FromJSON RepoStarred where+    parseJSON = withObject "RepoStarred" $ \o -> RepoStarred+        <$> 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
@@ -0,0 +1,92 @@+module GitHub.Data.Comments where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data Comment = Comment+    { commentPosition  :: !(Maybe Int)+    , commentLine      :: !(Maybe Int)+    , commentBody      :: !Text+    , commentCommitId  :: !(Maybe Text)+    , commentUpdatedAt :: !UTCTime+    , commentHtmlUrl   :: !(Maybe URL)+    , commentUrl       :: !URL+    , commentCreatedAt :: !(Maybe UTCTime)+    , commentPath      :: !(Maybe Text)+    , commentUser      :: !SimpleUser+    , commentId        :: !(Id Comment)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Comment+instance Binary Comment++instance FromJSON Comment where+    parseJSON = withObject "Comment" $ \o -> Comment+        <$> o .:? "position"+        <*> o .:? "line"+        <*> o .: "body"+        <*> o .:? "commit_id"+        <*> o .: "updated_at"+        <*> o .:? "html_url"+        <*> o .: "url"+        <*> o .: "created_at"+        <*> o .:? "path"+        <*> o .: "user"+        <*> o .: "id"++data NewComment = NewComment+    { newCommentBody :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewComment+instance Binary NewComment++instance ToJSON NewComment where+    toJSON (NewComment b) = object [ "body" .= b ]++data EditComment = EditComment+    { editCommentBody :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++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
@@ -0,0 +1,213 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}++module GitHub.Data.Content where++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, Eq, Ord, Generic)++instance NFData Content+instance Binary Content++data ContentFileData = ContentFileData {+   contentFileInfo     :: !ContentInfo+  ,contentFileEncoding :: !Text+  ,contentFileSize     :: !Int+  ,contentFileContent  :: !Text+} deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentFileData+instance Binary ContentFileData++-- | An item in a directory listing.+data ContentItem = ContentItem {+   contentItemType :: !ContentItemType+  ,contentItemInfo :: !ContentInfo+} deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentItem+instance Binary ContentItem++data ContentItemType = ItemFile | ItemDir+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentItemType+instance Binary ContentItemType++-- | Information common to both kinds of Content: files and directories.+data ContentInfo = ContentInfo {+   contentName    :: !Text+  ,contentPath    :: !Text+  ,contentSha     :: !Text+  ,contentUrl     :: !URL+  ,contentGitUrl  :: !URL+  ,contentHtmlUrl :: !URL+} deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentInfo+instance Binary ContentInfo++data ContentResultInfo = ContentResultInfo+    { contentResultInfo :: !ContentInfo+    , contentResultSize :: !Int+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentResultInfo+instance Binary ContentResultInfo++data ContentResult = ContentResult+    { contentResultContent  :: !ContentResultInfo+    , contentResultCommit   :: !GitCommit+    } deriving (Show, Data, Eq, Ord, Generic)++instance NFData ContentResult+instance Binary ContentResult++data Author = Author+    { authorName  :: !Text+    , authorEmail :: !Text+    }+    deriving (Eq, Ord, Show, Data, Generic)++instance NFData Author+instance Binary Author++data CreateFile = CreateFile+    { createFilePath      :: !Text+    , createFileMessage   :: !Text+    , createFileContent   :: !Text+    , createFileBranch    :: !(Maybe Text)+    , createFileAuthor    :: !(Maybe Author)+    , createFileCommitter :: !(Maybe Author)+    }+    deriving (Eq, Ord, Show, Data, Generic)++instance NFData CreateFile+instance Binary CreateFile++data UpdateFile = UpdateFile+    { updateFilePath      :: !Text+    , updateFileMessage   :: !Text+    , updateFileContent   :: !Text+    , updateFileSHA       :: !Text+    , updateFileBranch    :: !(Maybe Text)+    , updateFileAuthor    :: !(Maybe Author)+    , updateFileCommitter :: !(Maybe Author)+    }+    deriving (Eq, Ord, Show, Data, Generic)++instance NFData UpdateFile+instance Binary UpdateFile++data DeleteFile = DeleteFile+    { deleteFilePath      :: !Text+    , deleteFileMessage   :: !Text+    , deleteFileSHA       :: !Text+    , deleteFileBranch    :: !(Maybe Text)+    , deleteFileAuthor    :: !(Maybe Author)+    , deleteFileCommitter :: !(Maybe Author)+    }+    deriving (Eq, Ord, Show, Data, Generic)++instance NFData DeleteFile+instance Binary DeleteFile++instance FromJSON Content where+  parseJSON o@(Object _) = ContentFile <$> parseJSON o+  parseJSON (Array os) = ContentDirectory <$> traverse parseJSON os+  parseJSON _ = fail "Could not build a Content"++instance FromJSON ContentFileData where+  parseJSON = withObject "ContentFileData" $ \o ->+    ContentFileData <$> parseJSON (Object o)+                    <*> o .: "encoding"+                    <*> o .: "size"+                    <*> o .: "content"++instance FromJSON ContentItem where+  parseJSON = withObject "ContentItem" $ \o ->+    ContentItem <$> o .: "type"+                <*> parseJSON (Object o)++instance FromJSON ContentItemType where+  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 ->+    ContentInfo <$> o .: "name"+                <*> o .: "path"+                <*> o .: "sha"+                <*> o .: "url"+                <*> o .: "git_url"+                <*> o .: "html_url"++instance FromJSON ContentResultInfo where+  parseJSON = withObject "ContentResultInfo" $ \o ->+    ContentResultInfo <$> parseJSON (Object o)+                  <*> o .: "size"++instance FromJSON ContentResult where+  parseJSON = withObject "ContentResult" $ \o ->+    ContentResult <$> o .: "content"+                  <*> o .: "commit"++instance ToJSON Author where+  toJSON Author {..} = object+    [ "name"  .= authorName+    , "email" .= authorEmail+    ]++instance ToJSON CreateFile where+  toJSON CreateFile {..} = object $+    [ "path"       .= createFilePath+    , "message"    .= createFileMessage+    , "content"    .= createFileContent+    ]+    ++ "branch"    .=? createFileBranch+    ++ "author"    .=? createFileAuthor+    ++ "committer" .=? createFileCommitter++instance ToJSON UpdateFile where+  toJSON UpdateFile {..} = object $+    [ "path"       .= updateFilePath+    , "message"    .= updateFileMessage+    , "content"    .= updateFileContent+    , "sha"        .= updateFileSHA+    ]+    ++ "branch"    .=? updateFileBranch+    ++ "author"    .=? updateFileAuthor+    ++ "committer" .=? updateFileCommitter++instance ToJSON DeleteFile where+  toJSON DeleteFile {..} = object $+    [ "path"       .= deleteFilePath+    , "message"    .= deleteFileMessage+    , "sha"        .= deleteFileSHA+    ]+    ++ "branch"    .=? deleteFileBranch+    ++ "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
@@ -0,0 +1,388 @@+module GitHub.Data.Definitions where++import GitHub.Internal.Prelude+import Prelude ()++import Control.Monad       (mfilter)+import Data.Aeson.Types    (Parser)+import Network.HTTP.Client (HttpException)++import qualified Control.Exception as E+import qualified Data.ByteString   as BS+import qualified Data.Text         as T++import GitHub.Data.Id   (Id)+import GitHub.Data.Name (Name)+import GitHub.Data.URL  (URL (..))++-- | Errors have been tagged according to their source, so you can more easily+-- dispatch and handle them.+data Error+    = HTTPError !HttpException -- ^ A HTTP error occurred. The actual caught error is included.+    | ParseError !Text -- ^ An error in the parser itself.+    | JsonError !Text -- ^ The JSON is malformed or unexpected.+    | UserError !Text -- ^ Incorrect input.+    deriving (Show)++instance E.Exception Error++-- | Type of the repository owners.+data OwnerType = OwnerUser | OwnerOrganization | OwnerBot+    deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Data)++instance NFData OwnerType+instance Binary OwnerType++data SimpleUser = SimpleUser+    { simpleUserId        :: !(Id User)+    , simpleUserLogin     :: !(Name User)+    , simpleUserAvatarUrl :: !URL+    , simpleUserUrl       :: !URL+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData SimpleUser+instance Binary SimpleUser++data SimpleOrganization = SimpleOrganization+    { simpleOrganizationId        :: !(Id Organization)+    , simpleOrganizationLogin     :: !(Name Organization)+    , simpleOrganizationUrl       :: !URL+    , simpleOrganizationAvatarUrl :: !URL+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData SimpleOrganization+instance Binary SimpleOrganization++-- | Sometimes we don't know the type of the owner, e.g. in 'Repo'+data SimpleOwner = SimpleOwner+    { simpleOwnerId        :: !(Id Owner)+    , simpleOwnerLogin     :: !(Name Owner)+    , simpleOwnerUrl       :: !URL+    , simpleOwnerAvatarUrl :: !URL+    , simpleOwnerType      :: !OwnerType+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData SimpleOwner+instance Binary SimpleOwner++data User = User+    { userId          :: !(Id User)+    , userLogin       :: !(Name User)+    , userName        :: !(Maybe Text)+    , userType        :: !OwnerType  -- ^ Should always be 'OwnerUser' or 'OwnerBot'+    , userCreatedAt   :: !UTCTime+    , userPublicGists :: !Int+    , userAvatarUrl   :: !URL+    , userFollowers   :: !Int+    , userFollowing   :: !Int+    , userHireable    :: !(Maybe Bool)+    , userBlog        :: !(Maybe Text)+    , userBio         :: !(Maybe Text)+    , userPublicRepos :: !Int+    , userLocation    :: !(Maybe Text)+    , userCompany     :: !(Maybe Text)+    , userEmail       :: !(Maybe Text)+    , userUrl         :: !URL+    , userHtmlUrl     :: !URL+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData User+instance Binary User++data Organization = Organization+    { organizationId          :: !(Id Organization)+    , organizationLogin       :: !(Name Organization)+    , organizationName        :: !(Maybe Text)+    , organizationType        :: !OwnerType  -- ^ Should always be 'OwnerOrganization'+    , organizationBlog        :: !(Maybe Text)+    , organizationLocation    :: !(Maybe Text)+    , organizationFollowers   :: !Int+    , organizationCompany     :: !(Maybe Text)+    , organizationAvatarUrl   :: !URL+    , organizationPublicGists :: !Int+    , organizationHtmlUrl     :: !URL+    , organizationEmail       :: !(Maybe Text)+    , organizationFollowing   :: !Int+    , organizationPublicRepos :: !Int+    , organizationUrl         :: !URL+    , organizationCreatedAt   :: !UTCTime+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData Organization+instance Binary Organization++-- | In practice you can't have concrete values of 'Owner'.+newtype Owner = Owner (Either User Organization)+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData Owner+instance Binary Owner++fromOwner :: Owner -> Either User Organization+fromOwner (Owner owner) = owner++-- JSON instances++instance FromJSON OwnerType where+    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+        SimpleUser+            <$> obj .: "id"+            <*> obj .: "login"+            <*> obj .: "avatar_url"+            <*> obj .: "url"++instance FromJSON SimpleOrganization where+    parseJSON = withObject "SimpleOrganization" $ \obj ->+        SimpleOrganization+            <$> obj .: "id"+            <*> obj .: "login"+            <*> obj .: "url"+            <*> obj .: "avatar_url"++instance FromJSON SimpleOwner where+    parseJSON = withObject "SimpleOwner" $ \obj -> do+        SimpleOwner+            <$> obj .: "id"+            <*> obj .: "login"+            <*> obj .: "url"+            <*> obj .: "avatar_url"+            <*> obj .: "type"++parseUser :: Object -> Parser User+parseUser obj = User+    <$> obj .: "id"+    <*> obj .: "login"+    <*> obj .:? "name"+    <*> obj .: "type"+    <*> obj .: "created_at"+    <*> obj .: "public_gists"+    <*> obj .: "avatar_url"+    <*> obj .: "followers"+    <*> obj .: "following"+    <*> obj .:? "hireable"+    <*> obj .:? "blog"+    <*> obj .:? "bio"+    <*> obj .: "public_repos"+    <*> obj .:? "location"+    <*> obj .:? "company"+    <*> obj .:? "email"+    <*> obj .: "url"+    <*> obj .: "html_url"++parseOrganization :: Object -> Parser Organization+parseOrganization obj = Organization+    <$> obj .: "id"+    <*> obj .: "login"+    <*> obj .:? "name"+    <*> obj .: "type"+    <*> obj .:? "blog"+    <*> obj .:? "location"+    <*> obj .: "followers"+    <*> obj .:? "company"+    <*> obj .: "avatar_url"+    <*> obj .: "public_gists"+    <*> obj .: "html_url"+    <*> obj .:? "email"+    <*> obj .: "following"+    <*> obj .: "public_repos"+    <*> obj .: "url"+    <*> obj .: "created_at"++instance FromJSON User where+    parseJSON = mfilter ((/= OwnerOrganization) . userType) . withObject "User" parseUser++instance FromJSON Organization where+    parseJSON = withObject "Organization" parseOrganization++instance FromJSON Owner where+    parseJSON = withObject "Owner" $ \obj -> do+        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, 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, Data, Generic)++-- | Request query string+type QueryString = [(BS.ByteString, Maybe BS.ByteString)]++-- | 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+-------------------------------------------------------------------------------++data IssueLabel = IssueLabel+    { labelColor :: !Text+    , labelUrl   :: !URL+    , labelName  :: !(Name IssueLabel)+    , labelDesc  :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData IssueLabel+instance Binary IssueLabel++instance FromJSON IssueLabel where+    parseJSON = withObject "IssueLabel" $ \o -> IssueLabel+        <$> 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
@@ -0,0 +1,52 @@+-----------------------------------------------------------------------------+-- |+-- License     :  BSD-3-Clause+-- Maintainer  :  Todd Mohney <toddmohney@gmail.com>+--+module GitHub.Data.DeployKeys where++import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data RepoDeployKey = RepoDeployKey+    { repoDeployKeyId        :: !(Id RepoDeployKey)+    , repoDeployKeyKey       :: !Text+    , repoDeployKeyUrl       :: !URL+    , repoDeployKeyTitle     :: !Text+    , repoDeployKeyVerified  :: !Bool+    , repoDeployKeyCreatedAt :: !UTCTime+    , repoDeployKeyReadOnly  :: !Bool+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON RepoDeployKey where+    parseJSON = withObject "RepoDeployKey" $ \o -> RepoDeployKey+        <$> o .: "id"+        <*> o .: "key"+        <*> o .: "url"+        <*> o .: "title"+        <*> o .: "verified"+        <*> o .: "created_at"+        <*> o .: "read_only"++data NewRepoDeployKey = NewRepoDeployKey+    { newRepoDeployKeyKey      :: !Text+    , newRepoDeployKeyTitle    :: !Text+    , newRepoDeployKeyReadOnly :: !Bool+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance ToJSON NewRepoDeployKey where+    toJSON (NewRepoDeployKey key title readOnly) = object+        [ "key" .= key+        , "title" .= title+        , "read_only" .= readOnly+        ]++instance FromJSON NewRepoDeployKey where+    parseJSON = withObject "RepoDeployKey" $ \o -> NewRepoDeployKey+        <$> o .: "key"+        <*> o .: "title"+        <*> o .: "read_only"
+ 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
@@ -0,0 +1,37 @@+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, Eq, Ord, Generic)++instance NFData EmailVisibility+instance Binary EmailVisibility++instance FromJSON EmailVisibility where+    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, Eq, Ord, Generic)++instance NFData Email+instance Binary Email++instance FromJSON Email where+    parseJSON = withObject "Email" $ \o -> Email+        <$> o .:  "email"+        <*> o .:  "verified"+        <*> o .:  "primary"+        <*> o .:? "visibility"
+ 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
@@ -0,0 +1,29 @@+module GitHub.Data.Events where++import GitHub.Data.Definitions+import GitHub.Internal.Prelude+import Prelude ()++-- | Events.+--+-- /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, Eq, Ord, Generic)++instance NFData Event+instance Binary Event++instance FromJSON Event where+    parseJSON = withObject "Event" $ \obj -> Event+        -- <$> obj .: "id"+        <$> obj .: "actor"+        <*> obj .: "created_at"+        <*> obj .: "public"
+ src/GitHub/Data/Gists.hs view
@@ -0,0 +1,118 @@+module GitHub.Data.Gists where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id)+import GitHub.Data.Name        (Name)+import GitHub.Data.Repos       (Language)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data Gist = Gist+    { gistUser        :: !SimpleUser+    , gistGitPushUrl  :: !URL+    , gistUrl         :: !URL+    , gistDescription :: !(Maybe Text)+    , gistCreatedAt   :: !UTCTime+    , gistPublic      :: !Bool+    , gistComments    :: !Int+    , gistUpdatedAt   :: !UTCTime+    , gistHtmlUrl     :: !URL+    , gistId          :: !(Name Gist)+    , gistFiles       :: !(HashMap Text GistFile)+    , gistGitPullUrl  :: !URL+    } deriving (Show, Data, Eq, Generic)++instance NFData Gist+instance Binary Gist++instance FromJSON Gist where+    parseJSON = withObject "Gist" $ \o -> Gist+        <$> o .: "owner"+        <*> o .: "git_push_url"+        <*> o .: "url"+        <*> o .:? "description"+        <*> o .: "created_at"+        <*> o .: "public"+        <*> o .: "comments"+        <*> o .: "updated_at"+        <*> o .: "html_url"+        <*> o .: "id"+        <*> o .: "files"+        <*> o .: "git_push_url"++data GistFile = GistFile+    { gistFileType     :: !Text+    , gistFileRawUrl   :: !URL+    , gistFileSize     :: !Int+    , gistFileLanguage :: !(Maybe Language)+    , gistFileFilename :: !Text+    , gistFileContent  :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Generic)++instance NFData GistFile+instance Binary GistFile++instance FromJSON GistFile where+    parseJSON = withObject "GistFile" $ \o -> GistFile+        <$> o .: "type"+        <*> o .: "raw_url"+        <*> o .: "size"+        <*> o .:? "language"+        <*> o .: "filename"+        <*> o .:? "content"++data GistComment = GistComment+    { gistCommentUser      :: !SimpleUser+    , gistCommentUrl       :: !URL+    , gistCommentCreatedAt :: !UTCTime+    , gistCommentBody      :: !Text+    , gistCommentUpdatedAt :: !UTCTime+    , gistCommentId        :: !(Id GistComment)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GistComment+instance Binary GistComment++instance FromJSON GistComment where+    parseJSON = withObject "GistComment" $ \o -> GistComment+        <$> o .: "user"+        <*> o .: "url"+        <*> o .: "created_at"+        <*> 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
@@ -0,0 +1,312 @@+module GitHub.Data.GitData where++import GitHub.Data.Definitions+import GitHub.Data.Name        (Name)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Vector as V++-- | The options for querying commits.+data CommitQueryOption+    = CommitQuerySha !Text+    | CommitQueryPath !Text+    | CommitQueryAuthor !Text+    | CommitQuerySince !UTCTime+    | CommitQueryUntil !UTCTime+  deriving (Show, Eq, Ord, Generic, Data)++data Stats = Stats+    { statsAdditions :: !Int+    , statsTotal     :: !Int+    , statsDeletions :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Stats+instance Binary Stats++data Commit = Commit+    { commitSha       :: !(Name Commit)+    , commitParents   :: !(Vector Tree)+    , commitUrl       :: !URL+    , commitGitCommit :: !GitCommit+    , commitCommitter :: !(Maybe SimpleUser)+    , commitAuthor    :: !(Maybe SimpleUser)+    , commitFiles     :: !(Vector File)+    , commitStats     :: !(Maybe Stats)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Commit+instance Binary Commit++data Tree = Tree+    { treeSha      :: !(Name Tree)+    , treeUrl      :: !URL+    , treeGitTrees :: !(Vector GitTree)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Tree+instance Binary Tree++data GitTree = GitTree+    { gitTreeType :: !Text+    , gitTreeSha  :: !(Name GitTree)+    -- Can be empty for submodule+    , gitTreeUrl  :: !(Maybe URL)+    , gitTreeSize :: !(Maybe Int)+    , gitTreePath :: !Text+    , gitTreeMode :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GitTree+instance Binary GitTree++data GitCommit = GitCommit+    { gitCommitMessage   :: !Text+    , gitCommitUrl       :: !URL+    , gitCommitCommitter :: !GitUser+    , gitCommitAuthor    :: !GitUser+    , gitCommitTree      :: !Tree+    , gitCommitSha       :: !(Maybe (Name GitCommit))+    , gitCommitParents   :: !(Vector Tree)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GitCommit+instance Binary GitCommit++data Blob = Blob+    { blobUrl      :: !URL+    , blobEncoding :: !Text+    , blobContent  :: !Text+    , blobSha      :: !(Name Blob)+    , blobSize     :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Blob+instance Binary Blob++data Tag = Tag+    { tagName       :: !Text+    , tagZipballUrl :: !URL+    , tagTarballUrl :: !URL+    , tagCommit     :: !BranchCommit+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Tag+instance Binary Tag++data Branch = Branch+    { branchName   :: !Text+    , branchCommit :: !BranchCommit+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Branch++data BranchCommit = BranchCommit+    { branchCommitSha :: !Text+    , branchCommitUrl :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData BranchCommit+instance Binary BranchCommit++data Diff = Diff+    { diffStatus       :: !Text+    , diffBehindBy     :: !Int+    , diffPatchUrl     :: !URL+    , diffUrl          :: !URL+    , diffBaseCommit   :: !Commit+    , diffCommits      :: !(Vector Commit)+    , diffTotalCommits :: !Int+    , diffHtmlUrl      :: !URL+    , diffFiles        :: !(Vector File)+    , diffAheadBy      :: !Int+    , diffDiffUrl      :: !URL+    , diffPermalinkUrl :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Diff+instance Binary Diff++data NewGitReference = NewGitReference+    { newGitReferenceRef :: !Text+    , newGitReferenceSha :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewGitReference+instance Binary NewGitReference++data GitReference = GitReference+    { gitReferenceObject :: !GitObject+    , gitReferenceUrl    :: !URL+    , gitReferenceRef    :: !(Name GitReference)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GitReference+instance Binary GitReference++data GitObject = GitObject+    { gitObjectType :: !Text+    , gitObjectSha  :: !Text+    , gitObjectUrl  :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GitObject+instance Binary GitObject++data GitUser = GitUser+    { gitUserName  :: !Text+    , gitUserEmail :: !Text+    , gitUserDate  :: !UTCTime+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData GitUser+instance Binary GitUser++data File = File+    { fileBlobUrl   :: !(Maybe URL)+    , fileStatus    :: !Text+    , fileRawUrl    :: !(Maybe URL)+    , fileAdditions :: !Int+    , fileSha       :: !(Maybe Text)+    , fileChanges   :: !Int+    , filePatch     :: !(Maybe Text)+    , fileFilename  :: !Text+    , fileDeletions :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData File+instance Binary File++-- JSON instances++instance FromJSON Stats where+    parseJSON = withObject "Stats" $ \o -> Stats+        <$> o .: "additions"+        <*> o .: "total"+        <*> o .: "deletions"++instance FromJSON Commit where+    parseJSON = withObject "Commit" $ \o -> Commit+        <$> o .: "sha"+        <*> o .: "parents"+        <*> o .: "url"+        <*> o .: "commit"+        <*> (o .:? "committer" <|> pure Nothing)+        <*> (o .:? "author" <|> pure Nothing)+        <*> o .:? "files" .!= V.empty+        <*> o .:? "stats"++instance FromJSON Tree where+    parseJSON = withObject "Tree" $ \o -> Tree+        <$> o .: "sha"+        <*> o .: "url"+        <*> o .:? "tree" .!= V.empty++instance FromJSON GitTree where+    parseJSON = withObject "GitTree" $ \o -> GitTree+        <$> o .: "type"+        <*> o .: "sha"+        <*> o .:? "url"+        <*> o .:? "size"+        <*> o .: "path"+        <*> o .: "mode"++instance FromJSON GitCommit where+    parseJSON = withObject "GitCommit" $ \o -> GitCommit+        <$> o .: "message"+        <*> o .: "url"+        <*> o .: "committer"+        <*> o .: "author"+        <*> o .: "tree"+        <*> o .:? "sha"+        <*> o .:? "parents" .!= V.empty++instance FromJSON GitUser where+    parseJSON = withObject "GitUser" $ \o -> GitUser+        <$> o .: "name"+        <*> o .: "email"+        <*> o .: "date"++instance FromJSON File where+    parseJSON = withObject "File" $ \o -> File+        <$> o .:? "blob_url"+        <*> o .: "status"+        <*> o .:? "raw_url"+        <*> o .: "additions"+        <*> o .:? "sha"+        <*> o .: "changes"+        <*> o .:? "patch"+        <*> o .: "filename"+        <*> o .: "deletions"++instance ToJSON NewGitReference where+    toJSON (NewGitReference r s) = object [ "ref" .= r, "sha" .= s  ]++instance FromJSON GitReference where+    parseJSON = withObject "GitReference" $ \o -> GitReference+        <$> o .: "object"+        <*> o .: "url"+        <*> o .: "ref"++instance FromJSON GitObject where+    parseJSON = withObject "GitObject" $ \o -> GitObject+        <$> o .: "type"+        <*> o .: "sha"+        <*> o .: "url"++instance FromJSON Diff where+    parseJSON = withObject "Diff" $ \o -> Diff+        <$> o .: "status"+        <*> o .: "behind_by"+        <*> o .: "patch_url"+        <*> o .: "url"+        <*> o .: "base_commit"+        <*> o .:? "commits" .!= V.empty+        <*> o .: "total_commits"+        <*> o .: "html_url"+        <*> o .:? "files" .!= V.empty+        <*> o .: "ahead_by"+        <*> o .: "diff_url"+        <*> o .: "permalink_url"++instance FromJSON Blob where+    parseJSON = withObject "Blob" $ \o -> Blob+        <$> o .: "url"+        <*> o .: "encoding"+        <*> o .: "content"+        <*> o .: "sha"+        <*> o .: "size"++instance FromJSON Tag where+    parseJSON = withObject "Tag" $ \o -> Tag+        <$> o .: "name"+        <*> o .: "zipball_url"+        <*> o .: "tarball_url"+        <*> o .: "commit"++instance FromJSON Branch where+    parseJSON = withObject "Branch" $ \o -> Branch+        <$> o .: "name"+        <*> o .: "commit"++instance FromJSON BranchCommit where+    parseJSON = withObject "BranchCommit" $ \o -> BranchCommit+        <$> o .: "sha"+        <*> o .: "url"
+ src/GitHub/Data/Id.hs view
@@ -0,0 +1,31 @@+module GitHub.Data.Id (+    Id(..),+    mkId,+    untagId,+    ) where++import GitHub.Internal.Prelude+import Prelude ()++-- | Numeric identifier.+newtype Id entity = Id Int+    deriving (Eq, Ord, Show, Generic, Data)++-- | Smart constructor for 'Id'.+mkId :: proxy entity -> Int -> Id entity+mkId _ = Id++untagId :: Id entity -> Int+untagId (Id name) = name++instance Hashable (Id entity)+instance Binary (Id entity)++instance NFData (Id entity) where+    rnf (Id s) = rnf s++instance FromJSON (Id entity) where+    parseJSON = fmap Id . parseJSON++instance ToJSON (Id entity) where+    toJSON = toJSON . untagId
+ src/GitHub/Data/Invitation.hs view
@@ -0,0 +1,82 @@+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` ?+    , invitationLogin     :: !(Maybe (Name User))+    , invitationEmail     :: !(Maybe Text)+    , invitationRole      :: !InvitationRole+    , invitationCreatedAt :: !UTCTime+    , inviter             :: !SimpleUser+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Invitation+instance Binary Invitation++instance FromJSON Invitation where+    parseJSON = withObject "Invitation" $ \o -> Invitation+        <$> o .: "id"+        <*> o .:? "login"+        <*> o .:? "email"+        <*> o .: "role"+        <*> o .: "created_at"+        <*> o .: "inviter"+++data InvitationRole+    = InvitationRoleDirectMember+    | InvitationRoleAdmin+    | InvitationRoleBillingManager+    | InvitationRoleHiringManager+    | InvitationRoleReinstate+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData InvitationRole+instance Binary InvitationRole++instance FromJSON InvitationRole where+    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 $ "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
@@ -0,0 +1,227 @@+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, IssueStateReason)+import GitHub.Data.PullRequests+import GitHub.Data.URL          (URL)+import GitHub.Internal.Prelude+import Prelude                  ()++import qualified Data.Text as T++data Issue = Issue+    { issueClosedAt    :: !(Maybe UTCTime)+    , issueUpdatedAt   :: !UTCTime+    , issueEventsUrl   :: !URL+    , issueHtmlUrl     :: !(Maybe URL)+    , issueClosedBy    :: !(Maybe SimpleUser)+    , issueLabels      :: !(Vector IssueLabel)+    , issueNumber      :: !IssueNumber+    , issueAssignees   :: !(Vector SimpleUser)+    , issueUser        :: !SimpleUser+    , issueTitle       :: !Text+    , issuePullRequest :: !(Maybe PullRequestReference)+    , issueUrl         :: !URL+    , issueCreatedAt   :: !UTCTime+    , issueBody        :: !(Maybe Text)+    , issueState       :: !IssueState+    , issueId          :: !(Id Issue)+    , issueComments    :: !Int+    , issueMilestone   :: !(Maybe Milestone)+    , issueStateReason :: !(Maybe IssueStateReason)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Issue+instance Binary Issue++data NewIssue = NewIssue+    { newIssueTitle     :: !Text+    , newIssueBody      :: !(Maybe Text)+    , newIssueAssignees :: !(Vector (Name User))+    , newIssueMilestone :: !(Maybe (Id Milestone))+    , newIssueLabels    :: !(Maybe (Vector (Name IssueLabel)))+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewIssue+instance Binary NewIssue++data EditIssue = EditIssue+    { editIssueTitle     :: !(Maybe Text)+    , editIssueBody      :: !(Maybe Text)+    , editIssueAssignees :: !(Maybe (Vector (Name User)))+    , editIssueState     :: !(Maybe IssueState)+    , editIssueMilestone :: !(Maybe (Id Milestone))+    , editIssueLabels    :: !(Maybe (Vector (Name IssueLabel)))+    }+  deriving  (Show, Data, Eq, Ord, Generic)++instance NFData EditIssue+instance Binary EditIssue++data IssueComment = IssueComment+    { issueCommentUpdatedAt :: !UTCTime+    , issueCommentUser      :: !SimpleUser+    , issueCommentUrl       :: !URL+    , issueCommentHtmlUrl   :: !URL+    , issueCommentCreatedAt :: !UTCTime+    , issueCommentBody      :: !Text+    , issueCommentId        :: !Int+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData IssueComment+instance Binary IssueComment++-- | See <https://developer.github.com/v3/issues/events/#events-1>+data EventType+    = Mentioned             -- ^ The actor was @mentioned in an issue body.+    | Subscribed            -- ^ The actor subscribed to receive notifications for an issue.+    | Unsubscribed          -- ^ The issue was unsubscribed from by the actor.+    | Referenced            -- ^ The issue was referenced from a commit message. The commit_id attribute is the commit SHA1 of where that happened.+    | Merged                -- ^ The issue was merged by the actor. The commit_id attribute is the SHA1 of the HEAD commit that was merged.+    | Assigned              -- ^ The issue was assigned to the actor.+    | Closed                -- ^ The issue was closed by the actor. When the commit_id is present, it identifies the commit that closed the issue using “closes / fixes #NN” syntax.+    | Reopened              -- ^ The issue was reopened by the actor.+    | ActorUnassigned       -- ^ The issue was unassigned to the actor+    | Labeled               -- ^ A label was added to the issue.+    | Unlabeled             -- ^ A label was removed from the issue.+    | Milestoned            -- ^ The issue was added to a milestone.+    | Demilestoned          -- ^ The issue was removed from a milestone.+    | Renamed               -- ^ The issue title was changed.+    | Locked                -- ^ The issue was locked by the actor.+    | Unlocked              -- ^ The issue was unlocked by the actor.+    | HeadRefDeleted        -- ^ The pull request’s branch was deleted.+    | HeadRefRestored       -- ^ The pull request’s branch was restored.+    | ReviewRequested       -- ^ The actor requested review from the subject on this pull request.+    | ReviewDismissed       -- ^ The actor dismissed a review from the pull request.+    | ReviewRequestRemoved  -- ^ The actor removed the review request for the subject on this pull request.+    | MarkedAsDuplicate     -- ^ A user with write permissions marked an issue as a duplicate of another issue or a pull request as a duplicate of another pull request.+    | UnmarkedAsDuplicate   -- ^ An issue that a user had previously marked as a duplicate of another issue is no longer considered a duplicate, or a pull request that a user had previously marked as a duplicate of another pull request is no longer considered a duplicate.+    | AddedToProject        -- ^ The issue was added to a project board.+    | 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, Eq, Ord, Generic)++instance NFData EventType+instance Binary EventType++-- | Issue event+data IssueEvent = IssueEvent+    { issueEventActor     :: !SimpleUser+    , issueEventType      :: !EventType+    , issueEventCommitId  :: !(Maybe Text)+    , issueEventUrl       :: !URL+    , issueEventCreatedAt :: !UTCTime+    , issueEventId        :: !Int+    , issueEventIssue     :: !(Maybe Issue)+    , issueEventLabel     :: !(Maybe IssueLabel)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData IssueEvent+instance Binary IssueEvent++instance FromJSON IssueEvent where+    parseJSON = withObject "Event" $ \o -> IssueEvent+        <$> o .: "actor"+        <*> o .: "event"+        <*> o .:? "commit_id"+        <*> o .: "url"+        <*> o .: "created_at"+        <*> o .: "id"+        <*> o .:? "issue"+        <*> o .:? "label"++instance FromJSON EventType where+    parseJSON = withText "EventType" $ \t -> case T.toLower t of+        "closed"                   -> pure Closed+        "reopened"                 -> pure Reopened+        "subscribed"               -> pure Subscribed+        "merged"                   -> pure Merged+        "referenced"               -> pure Referenced+        "mentioned"                -> pure Mentioned+        "assigned"                 -> pure Assigned+        "unassigned"               -> pure ActorUnassigned+        "labeled"                  -> pure Labeled+        "unlabeled"                -> pure Unlabeled+        "milestoned"               -> pure Milestoned+        "demilestoned"             -> pure Demilestoned+        "renamed"                  -> pure Renamed+        "locked"                   -> pure Locked+        "unlocked"                 -> pure Unlocked+        "head_ref_deleted"         -> pure HeadRefDeleted+        "head_ref_restored"        -> pure HeadRefRestored+        "review_requested"         -> pure ReviewRequested+        "review_dismissed"         -> pure ReviewDismissed+        "review_request_removed"   -> pure ReviewRequestRemoved+        "marked_as_duplicate"      -> pure MarkedAsDuplicate+        "unmarked_as_duplicate"    -> pure UnmarkedAsDuplicate+        "added_to_project"         -> pure AddedToProject+        "moved_columns_in_project" -> pure MovedColumnsInProject+        "removed_from_project"     -> pure RemovedFromProject+        "converted_note_to_issue"  -> pure ConvertedNoteToIssue+        "unsubscribed"             -> pure Unsubscribed -- not in api docs list+        _                          -> fail $ "Unknown EventType: " <> T.unpack t++instance FromJSON IssueComment where+    parseJSON = withObject "IssueComment" $ \o -> IssueComment+        <$> o .: "updated_at"+        <*> o .: "user"+        <*> o .: "url"+        <*> o .: "html_url"+        <*> o .: "created_at"+        <*> o .: "body"+        <*> o .: "id"++instance FromJSON Issue where+    parseJSON = withObject "Issue" $ \o -> Issue+        <$> o .:? "closed_at"+        <*> o .: "updated_at"+        <*> o .: "events_url"+        <*> o .: "html_url"+        <*> o .:? "closed_by"+        <*> o .: "labels"+        <*> o .: "number"+        <*> o .: "assignees"+        <*> o .: "user"+        <*> o .: "title"+        <*> o .:? "pull_request"+        <*> o .: "url"+        <*> o .: "created_at"+        <*> o .: "body"+        <*> o .: "state"+        <*> o .: "id"+        <*> o .: "comments"+        <*> o .:? "milestone"+        <*> o .:? "state_reason"++instance ToJSON NewIssue where+    toJSON (NewIssue t b a m ls) = object $ filter notNull+        [ "title"     .= t+        , "body"      .= b+        , "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+        [ "title"     .= t+        , "body"      .= b+        , "assignees" .= a+        , "state"     .= s+        , "milestone" .= m+        , "labels"    .= ls+        ]+      where+        notNull (_, Null) = False+        notNull (_, _)    = True
+ src/GitHub/Data/Milestone.hs view
@@ -0,0 +1,83 @@+module GitHub.Data.Milestone where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data Milestone = Milestone+    { milestoneCreator      :: !SimpleUser+    , milestoneDueOn        :: !(Maybe UTCTime)+    , milestoneOpenIssues   :: !Int+    , milestoneNumber       :: !(Id Milestone)+    , milestoneClosedIssues :: !Int+    , milestoneDescription  :: !(Maybe Text)+    , milestoneTitle        :: !Text+    , milestoneUrl          :: !URL+    , milestoneCreatedAt    :: !UTCTime+    , milestoneState        :: !Text+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Milestone+instance Binary Milestone++instance FromJSON Milestone where+    parseJSON = withObject "Milestone" $ \o -> Milestone+        <$> o .: "creator"+        <*> o .: "due_on"+        <*> o .: "open_issues"+        <*> o .: "number"+        <*> o .: "closed_issues"+        <*> o .: "description"+        <*> o .: "title"+        <*> 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
@@ -0,0 +1,44 @@+module GitHub.Data.Name (+    Name(..),+    mkName,+    untagName,+    ) where++import Prelude ()+import GitHub.Internal.Prelude++import Data.Aeson.Types+       (FromJSONKey (..), ToJSONKey (..), fromJSONKeyCoerce, toJSONKeyText)++newtype Name entity = N Text+    deriving (Eq, Ord, Show, Generic, Data)++-- | Smart constructor for 'Name'+mkName :: proxy entity -> Text -> Name entity+mkName _ = N++untagName :: Name entity -> Text+untagName (N name) = name++instance Hashable (Name entity)+instance Binary (Name entity)++instance NFData (Name entity) where+    rnf (N s) = rnf s++instance FromJSON (Name entity) where+    parseJSON = fmap N . parseJSON++instance ToJSON (Name entity) where+    toJSON = toJSON . untagName++instance IsString (Name entity) where+    fromString = N . fromString++-- | @since 0.15.0.0+instance ToJSONKey (Name entity) where+    toJSONKey = toJSONKeyText untagName++-- | @since 0.15.0.0+instance FromJSONKey (Name entity) where+    fromJSONKey = fromJSONKeyCoerce
+ src/GitHub/Data/Options.hs view
@@ -0,0 +1,939 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE LambdaCase #-}++-- |+-- Module with modifiers for pull requests' and issues' listings.++module GitHub.Data.Options (+    -- * Common modifiers+    stateOpen,+    stateClosed,+    stateAll,+    sortAscending,+    sortDescending,+    sortByCreated,+    sortByUpdated,+    -- * Pull Requests+    PullRequestMod,+    prModToQueryString,+    optionsBase,+    optionsNoBase,+    optionsHead,+    optionsNoHead,+    sortByPopularity,+    sortByLongRunning,+    -- * Issues+    IssueMod,+    issueModToQueryString,+    sortByComments,+    optionsLabels,+    optionsSince,+    optionsSinceAll,+    optionsAssignedIssues,+    optionsCreatedIssues,+    optionsMentionedIssues,+    optionsSubscribedIssues,+    optionsAllIssues,+    -- * 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,+    HasDirection,+    HasCreatedUpdated,+    HasComments,+    HasLabels,+    HasSince,+    ) where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id, untagId)+import GitHub.Data.Milestone   (Milestone)+import GitHub.Data.Name        (Name, untagName)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Text          as T+import qualified Data.Text.Encoding as TE++-------------------------------------------------------------------------------+-- Data+-------------------------------------------------------------------------------++-- | 'GitHub.Data.Issues.Issue' or 'GitHub.Data.PullRequests.PullRequest' state+data IssueState+    = StateOpen+    | StateClosed+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance ToJSON IssueState where+    toJSON StateOpen    = String "open"+    toJSON StateClosed  = String "closed"++instance FromJSON IssueState where+    parseJSON = withText "IssueState" $ \t -> case T.toLower t of+        "open"   -> pure StateOpen+        "closed" -> pure StateClosed+        _        -> fail $ "Unknown IssueState: " <> T.unpack t++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+    | StateClean+    | StateDirty+    | StateUnstable+    | StateBlocked+    | StateBehind+    | StateDraft+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance ToJSON MergeableState where+    toJSON StateUnknown  = String "unknown"+    toJSON StateClean    = String "clean"+    toJSON StateDirty    = String "dirty"+    toJSON StateUnstable = String "unstable"+    toJSON StateBlocked  = String "blocked"+    toJSON StateBehind   = String "behind"+    toJSON StateDraft    = String "draft"++instance FromJSON MergeableState where+    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+instance Binary MergeableState++data SortDirection+    = SortAscending+    | SortDescending+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData SortDirection+instance Binary SortDirection++-- PR++data SortPR+    = SortPRCreated+    | SortPRUpdated+    | SortPRPopularity+    | SortPRLongRunning+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData SortPR+instance Binary SortPR++-- Issue+data IssueFilter+    = IssueFilterAssigned+    | IssueFilterCreated+    | IssueFilterMentioned+    | IssueFilterSubscribed+    | IssueFilterAll+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData IssueFilter+instance Binary IssueFilter++data SortIssue+    = SortIssueCreated+    | SortIssueUpdated+    | SortIssueComments+  deriving+    (Eq, Ord, Show, Enum, Bounded, Generic, Data)++instance NFData SortIssue+instance Binary SortIssue++data FilterBy a+    = FilterAny+    | FilterNone+    | FilterBy a+    | FilterNotSpecified+      -- ^ e.g. for milestones "any" means "any milestone".+      -- I.e. won't show issues without mileston specified+  deriving+    (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+-------------------------------------------------------------------------------++class HasState mod where+    state :: Maybe IssueState -> mod++stateOpen :: HasState mod => mod+stateOpen = state (Just StateOpen)++stateClosed :: HasState mod => mod+stateClosed = state (Just StateClosed)++stateAll :: HasState mod => mod+stateAll = state Nothing++instance HasState PullRequestMod where+    state s = PRMod $ \opts ->+        opts { pullRequestOptionsState = s }++instance HasState IssueMod where+    state s = IssueMod $ \opts ->+        opts { issueOptionsState = s }++instance HasState IssueRepoMod where+    state s = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsState = s }+++class HasDirection mod where+    sortDir :: SortDirection -> mod++sortAscending :: HasDirection mod => mod+sortAscending = sortDir SortAscending++sortDescending :: HasDirection mod => mod+sortDescending = sortDir SortDescending++instance HasDirection PullRequestMod where+    sortDir x = PRMod $ \opts ->+        opts { pullRequestOptionsDirection = x }++instance HasDirection IssueMod where+    sortDir x = IssueMod $ \opts ->+        opts { issueOptionsDirection = x }++instance HasDirection IssueRepoMod where+    sortDir x = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsDirection = x }+++class HasCreatedUpdated mod where+    sortByCreated :: mod+    sortByUpdated :: mod++instance HasCreatedUpdated PullRequestMod where+    sortByCreated = PRMod $ \opts ->+        opts { pullRequestOptionsSort = SortPRCreated }+    sortByUpdated = PRMod $ \opts ->+        opts { pullRequestOptionsSort = SortPRUpdated }++instance HasCreatedUpdated IssueMod where+    sortByCreated = IssueMod $ \opts ->+        opts { issueOptionsSort = SortIssueCreated }+    sortByUpdated = IssueMod $ \opts ->+        opts { issueOptionsSort = SortIssueUpdated }++instance HasCreatedUpdated IssueRepoMod where+    sortByCreated = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsSort = SortIssueCreated }+    sortByUpdated = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsSort = SortIssueUpdated }++-------------------------------------------------------------------------------+-- Pull Request+-------------------------------------------------------------------------------++-- | See <https://developer.github.com/v3/pulls/#parameters>.+data PullRequestOptions = PullRequestOptions+    { pullRequestOptionsState     :: !(Maybe IssueState)+    , pullRequestOptionsHead      :: !(Maybe Text)+    , pullRequestOptionsBase      :: !(Maybe Text)+    , pullRequestOptionsSort      :: !SortPR+    , pullRequestOptionsDirection :: !SortDirection+    }+  deriving+    (Eq, Ord, Show, Generic, Data)++defaultPullRequestOptions :: PullRequestOptions+defaultPullRequestOptions = PullRequestOptions+    { pullRequestOptionsState     = Just StateOpen+    , pullRequestOptionsHead      = Nothing+    , pullRequestOptionsBase      = Nothing+    , pullRequestOptionsSort      = SortPRCreated+    , pullRequestOptionsDirection = SortDescending+    }++-- | See <https://developer.github.com/v3/pulls/#parameters>.+newtype PullRequestMod = PRMod (PullRequestOptions -> PullRequestOptions)++instance Semigroup PullRequestMod where+    PRMod f <> PRMod g = PRMod (g . f)++instance Monoid PullRequestMod where+    mempty  = PRMod id+    mappend = (<>)++toPullRequestOptions :: PullRequestMod -> PullRequestOptions+toPullRequestOptions (PRMod f) = f defaultPullRequestOptions++prModToQueryString :: PullRequestMod -> QueryString+prModToQueryString = pullRequestOptionsToQueryString . toPullRequestOptions++pullRequestOptionsToQueryString :: PullRequestOptions -> QueryString+pullRequestOptionsToQueryString (PullRequestOptions st head_ base sort dir) =+    [ mk "state"     state'+    , mk "sort"      sort'+    , mk "direction" direction'+    ] ++ catMaybes+    [ mk "head" <$> head'+    , mk "base" <$> base'+    ]+  where+    mk k v = (k, Just v)+    state' = case st of+        Nothing          -> "all"+        Just StateOpen   -> "open"+        Just StateClosed -> "closed"+    sort' = case sort of+        SortPRCreated     -> "created"+        SortPRUpdated     -> "updated"+        SortPRPopularity  -> "popularity"+        SortPRLongRunning -> "long-running"+    direction' = case dir of+       SortDescending -> "desc"+       SortAscending  -> "asc"+    head' = fmap TE.encodeUtf8 head_+    base' = fmap TE.encodeUtf8 base++-------------------------------------------------------------------------------+-- Pull request modifiers+-------------------------------------------------------------------------------++optionsBase :: Text -> PullRequestMod+optionsBase x = PRMod $ \opts ->+    opts { pullRequestOptionsBase = Just x }++optionsNoBase :: PullRequestMod+optionsNoBase = PRMod $ \opts ->+    opts { pullRequestOptionsBase = Nothing }++optionsHead :: Text -> PullRequestMod+optionsHead x = PRMod $ \opts ->+    opts { pullRequestOptionsHead = Just x }++optionsNoHead :: PullRequestMod+optionsNoHead = PRMod $ \opts ->+    opts { pullRequestOptionsHead = Nothing }++sortByPopularity :: PullRequestMod+sortByPopularity = PRMod $ \opts ->+    opts { pullRequestOptionsSort = SortPRPopularity }++sortByLongRunning :: PullRequestMod+sortByLongRunning = PRMod $ \opts ->+    opts { pullRequestOptionsSort = SortPRLongRunning }++-------------------------------------------------------------------------------+-- Issues+-------------------------------------------------------------------------------++-- | 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)+    , issueOptionsLabels    :: ![Name IssueLabel] -- TODO: change to newtype+    , issueOptionsSort      :: !SortIssue+    , issueOptionsDirection :: !SortDirection+    , issueOptionsSince     :: !(Maybe UTCTime)+    }+  deriving+    (Eq, Ord, Show, Generic, Data)++defaultIssueOptions :: IssueOptions+defaultIssueOptions = IssueOptions+    { issueOptionsFilter    = IssueFilterAssigned+    , issueOptionsState     = Just StateOpen+    , issueOptionsLabels    = []+    , issueOptionsSort      = SortIssueCreated+    , issueOptionsDirection = SortDescending+    , issueOptionsSince     = Nothing+    }++-- | 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+    IssueMod f <> IssueMod g = IssueMod (g . f)++instance Monoid IssueMod where+    mempty  = IssueMod id+    mappend = (<>)++toIssueOptions :: IssueMod -> IssueOptions+toIssueOptions (IssueMod f) = f defaultIssueOptions++issueModToQueryString :: IssueMod -> QueryString+issueModToQueryString = issueOptionsToQueryString . toIssueOptions++issueOptionsToQueryString :: IssueOptions -> QueryString+issueOptionsToQueryString (IssueOptions filt st labels sort dir since) =+    [ mk "state"     state'+    , mk "sort"      sort'+    , mk "direction" direction'+    , mk "filter" filt'+    ] ++ catMaybes+    [ mk "labels" <$> labels'+    , mk "since" <$> since'+    ]+  where+    mk k v = (k, Just v)+    filt' = case filt of+        IssueFilterAssigned   -> "assigned"+        IssueFilterCreated    -> "created"+        IssueFilterMentioned  -> "mentioned"+        IssueFilterSubscribed -> "subscribed"+        IssueFilterAll        -> "all"+    state' = case st of+        Nothing          -> "all"+        Just StateOpen   -> "open"+        Just StateClosed -> "closed"+    sort' = case sort of+        SortIssueCreated  -> "created"+        SortIssueUpdated  -> "updated"+        SortIssueComments -> "comments"+    direction' = case dir of+       SortDescending -> "desc"+       SortAscending  -> "asc"++    since' = fmap (TE.encodeUtf8 . T.pack . show) since+    labels' = TE.encodeUtf8 . T.intercalate "," . fmap untagName <$> nullToNothing labels++nullToNothing :: Foldable f => f a -> Maybe (f a)+nullToNothing xs+    | null xs   = Nothing+    | otherwise = Just xs++-------------------------------------------------------------------------------+-- Issues modifiers+-------------------------------------------------------------------------------++class HasComments mod where+    sortByComments :: mod++instance HasComments IssueMod where+    sortByComments = IssueMod $ \opts ->+        opts { issueOptionsSort = SortIssueComments }++instance HasComments IssueRepoMod where+    sortByComments = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsSort = SortIssueComments }+++class HasLabels mod where+    optionsLabels :: Foldable f => f (Name IssueLabel) -> mod++instance HasLabels IssueMod where+    optionsLabels lbls = IssueMod $ \opts ->+        opts { issueOptionsLabels = toList lbls }++instance HasLabels IssueRepoMod where+    optionsLabels lbls = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsLabels = toList lbls }+++class HasSince mod where+    optionsSince :: UTCTime -> mod+    optionsSinceAll :: mod++instance HasSince IssueMod where+    optionsSince since = IssueMod $ \opts ->+        opts { issueOptionsSince = Just since }+    optionsSinceAll = IssueMod $ \opts ->+        opts { issueOptionsSince = Nothing }++instance HasSince IssueRepoMod where+    optionsSince since = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsSince = Just since }+    optionsSinceAll = IssueRepoMod $ \opts ->+        opts { issueRepoOptionsSince = Nothing }++-------------------------------------------------------------------------------+-- Only issues modifiers+-------------------------------------------------------------------------------++optionsAssignedIssues, optionsCreatedIssues, optionsMentionedIssues,+  optionsSubscribedIssues, optionsAllIssues  :: IssueMod+optionsAssignedIssues   = issueFilter IssueFilterAssigned+optionsCreatedIssues    = issueFilter IssueFilterCreated+optionsMentionedIssues  = issueFilter IssueFilterMentioned+optionsSubscribedIssues = issueFilter IssueFilterSubscribed+optionsAllIssues        = issueFilter IssueFilterAll++issueFilter :: IssueFilter -> IssueMod+issueFilter f = IssueMod $ \opts ->+    opts { issueOptionsFilter = f }++-------------------------------------------------------------------------------+-- 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))   -- ^ '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, Data)++defaultIssueRepoOptions :: IssueRepoOptions+defaultIssueRepoOptions = IssueRepoOptions+    { issueRepoOptionsMilestone = FilterNotSpecified+    , issueRepoOptionsState     = (Just StateOpen)+    , issueRepoOptionsAssignee  = FilterNotSpecified+    , issueRepoOptionsCreator   = Nothing+    , issueRepoOptionsMentioned = Nothing+    , issueRepoOptionsLabels    = []+    , issueRepoOptionsSort      = SortIssueCreated+    , issueRepoOptionsDirection = SortDescending+    , issueRepoOptionsSince     = Nothing+    }++-- | See <https://developer.github.com/v3/issues/#parameters-1>.+newtype IssueRepoMod = IssueRepoMod (IssueRepoOptions -> IssueRepoOptions)++instance Semigroup IssueRepoMod where+    IssueRepoMod f <> IssueRepoMod g = IssueRepoMod (g . f)++instance Monoid IssueRepoMod where+    mempty  = IssueRepoMod id+    mappend = (<>)++toIssueRepoOptions :: IssueRepoMod -> IssueRepoOptions+toIssueRepoOptions (IssueRepoMod f) = f defaultIssueRepoOptions++issueRepoModToQueryString :: IssueRepoMod -> QueryString+issueRepoModToQueryString = issueRepoOptionsToQueryString . toIssueRepoOptions++issueRepoOptionsToQueryString :: IssueRepoOptions -> QueryString+issueRepoOptionsToQueryString IssueRepoOptions {..} =+    [ mk "state"     state'+    , mk "sort"      sort'+    , mk "direction" direction'+    ] ++ catMaybes+    [ mk "milestone" <$> milestone'+    , mk "assignee"  <$> assignee'+    , mk "labels"    <$> labels'+    , mk "since"     <$> since'+    , mk "creator"   <$> creator'+    , mk "mentioned" <$> mentioned'+    ]+  where+    mk k v = (k, Just v)+    filt f x = case x of+        FilterAny          -> Just "*"+        FilterNone         -> Just "none"+        FilterBy x'        -> Just $ TE.encodeUtf8 $ f x'+        FilterNotSpecified -> Nothing++    milestone' = filt (T.pack . show . untagId) issueRepoOptionsMilestone+    assignee'  = filt untagName issueRepoOptionsAssignee++    state' = case issueRepoOptionsState of+        Nothing          -> "all"+        Just StateOpen   -> "open"+        Just StateClosed -> "closed"+    sort' = case issueRepoOptionsSort of+        SortIssueCreated  -> "created"+        SortIssueUpdated  -> "updated"+        SortIssueComments -> "comments"+    direction' = case issueRepoOptionsDirection of+       SortDescending -> "desc"+       SortAscending  -> "asc"++    since'     = TE.encodeUtf8 . T.pack . show <$> issueRepoOptionsSince+    labels'    = TE.encodeUtf8 . T.intercalate "," . fmap untagName <$> nullToNothing issueRepoOptionsLabels+    creator'   = TE.encodeUtf8 . untagName <$> issueRepoOptionsCreator+    mentioned' = TE.encodeUtf8 . untagName <$> issueRepoOptionsMentioned++-------------------------------------------------------------------------------+-- Issues repo modifiers+-------------------------------------------------------------------------------++-- | 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.+--+-- See <https://developer.github.com/v3/issues/#list-issues-for-a-repository>+optionsIrrelevantMilestone :: IssueRepoMod+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
@@ -0,0 +1,319 @@+module GitHub.Data.PullRequests (+    SimplePullRequest(..),+    PullRequest(..),+    EditPullRequest(..),+    CreatePullRequest(..),+    PullRequestLinks(..),+    PullRequestCommit(..),+    PullRequestEvent(..),+    PullRequestEventType(..),+    PullRequestReference(..),+    MergeResult(..),+    ) where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id)+import GitHub.Data.Options     (IssueState (..), MergeableState (..))+import GitHub.Data.Repos       (Repo)+import GitHub.Data.URL         (URL)+import GitHub.Data.Teams       (SimpleTeam)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Text as T++data SimplePullRequest = SimplePullRequest+    { simplePullRequestClosedAt           :: !(Maybe UTCTime)+    , simplePullRequestCreatedAt          :: !UTCTime+    , simplePullRequestUser               :: !SimpleUser+    , simplePullRequestPatchUrl           :: !URL+    , simplePullRequestState              :: !IssueState+    , simplePullRequestNumber             :: !IssueNumber+    , simplePullRequestHtmlUrl            :: !URL+    , simplePullRequestUpdatedAt          :: !UTCTime+    , simplePullRequestBody               :: !(Maybe Text)+    , simplePullRequestAssignees          :: (Vector SimpleUser)+    , simplePullRequestRequestedReviewers :: (Vector SimpleUser)+    , simplePullRequestRequestedTeamReviewers:: (Vector SimpleTeam)+    , simplePullRequestIssueUrl           :: !URL+    , simplePullRequestDiffUrl            :: !URL+    , simplePullRequestUrl                :: !URL+    , simplePullRequestLinks              :: !PullRequestLinks+    , simplePullRequestMergedAt           :: !(Maybe UTCTime)+    , simplePullRequestTitle              :: !Text+    , simplePullRequestId                 :: !(Id PullRequest)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData SimplePullRequest+instance Binary SimplePullRequest++data PullRequest = PullRequest+    { pullRequestClosedAt             :: !(Maybe UTCTime)+    , pullRequestCreatedAt            :: !UTCTime+    , pullRequestUser                 :: !SimpleUser+    , pullRequestPatchUrl             :: !URL+    , pullRequestState                :: !IssueState+    , pullRequestNumber               :: !IssueNumber+    , pullRequestHtmlUrl              :: !URL+    , pullRequestUpdatedAt            :: !UTCTime+    , pullRequestBody                 :: !(Maybe Text)+    , pullRequestAssignees            :: (Vector SimpleUser)+    , pullRequestRequestedReviewers   :: (Vector SimpleUser)+    , pullRequestRequestedTeamReviewers :: (Vector SimpleTeam)+    , pullRequestIssueUrl             :: !URL+    , pullRequestDiffUrl              :: !URL+    , pullRequestUrl                  :: !URL+    , pullRequestLinks                :: !PullRequestLinks+    , pullRequestMergedAt             :: !(Maybe UTCTime)+    , pullRequestTitle                :: !Text+    , pullRequestId                   :: !(Id PullRequest)+    , pullRequestMergedBy             :: !(Maybe SimpleUser)+    , pullRequestChangedFiles         :: !Int+    , pullRequestHead                 :: !PullRequestCommit+    , pullRequestComments             :: !Count+    , pullRequestDeletions            :: !Count+    , pullRequestAdditions            :: !Count+    , pullRequestReviewComments       :: !Count+    , pullRequestBase                 :: !PullRequestCommit+    , pullRequestCommits              :: !Count+    , pullRequestMerged               :: !Bool+    , pullRequestMergeable            :: !(Maybe Bool)+    , pullRequestMergeableState       :: !MergeableState+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullRequest+instance Binary PullRequest++data EditPullRequest = EditPullRequest+    { editPullRequestTitle :: !(Maybe Text)+    , editPullRequestBody  :: !(Maybe Text)+    , editPullRequestState :: !(Maybe IssueState)+    , editPullRequestBase  :: !(Maybe Text)+    , editPullRequestMaintainerCanModify+                           :: !(Maybe Bool)+    }+  deriving (Show, Generic)++instance NFData EditPullRequest+instance Binary EditPullRequest++data CreatePullRequest+    = CreatePullRequest+      { createPullRequestTitle :: !Text+      , createPullRequestBody  :: !Text+      , createPullRequestHead  :: !Text+      , createPullRequestBase  :: !Text+      }+    | CreatePullRequestIssue+      { createPullRequestIssueNum :: !Int+      , createPullRequestHead     :: !Text+      , createPullRequestBase     :: !Text+      }+  deriving (Show, Generic)++instance NFData CreatePullRequest+instance Binary CreatePullRequest++data PullRequestLinks = PullRequestLinks+    { pullRequestLinksReviewComments :: !URL+    , pullRequestLinksComments       :: !URL+    , pullRequestLinksHtml           :: !URL+    , pullRequestLinksSelf           :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullRequestLinks+instance Binary PullRequestLinks++data PullRequestCommit = PullRequestCommit+    { pullRequestCommitLabel :: !Text+    , pullRequestCommitRef   :: !Text+    , pullRequestCommitSha   :: !Text+    , pullRequestCommitUser  :: !SimpleUser+    , pullRequestCommitRepo  :: !(Maybe Repo)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullRequestCommit+instance Binary PullRequestCommit++data PullRequestEvent = PullRequestEvent+    { pullRequestEventAction      :: !PullRequestEventType+    , pullRequestEventNumber      :: !Int+    , pullRequestEventPullRequest :: !PullRequest+    , pullRequestRepository       :: !Repo+    , pullRequestSender           :: !SimpleUser+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullRequestEvent+instance Binary PullRequestEvent++data PullRequestEventType+    = PullRequestOpened+    | PullRequestClosed+    | PullRequestSynchronized+    | PullRequestReopened+    | PullRequestAssigned+    | PullRequestUnassigned+    | PullRequestLabeled+    | PullRequestUnlabeled+    | PullRequestReviewRequested+    | PullRequestReviewRequestRemoved+    | PullRequestEdited+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData PullRequestEventType+instance Binary PullRequestEventType++data PullRequestReference = PullRequestReference+    { pullRequestReferenceHtmlUrl  :: !(Maybe URL)+    , pullRequestReferencePatchUrl :: !(Maybe URL)+    , pullRequestReferenceDiffUrl  :: !(Maybe URL)+    }+    deriving (Eq, Ord, Show, Generic, Data)++instance NFData PullRequestReference+instance Binary PullRequestReference+++-------------------------------------------------------------------------------+-- JSON instances+-------------------------------------------------------------------------------++instance FromJSON SimplePullRequest where+    parseJSON = withObject "SimplePullRequest" $ \o -> SimplePullRequest+        <$> o .:? "closed_at"+        <*> o .: "created_at"+        <*> o .: "user"+        <*> o .: "patch_url"+        <*> o .: "state"+        <*> o .: "number"+        <*> o .: "html_url"+        <*> o .: "updated_at"+        <*> o .:? "body"+        <*> o .: "assignees"+        <*> o .:? "requested_reviewers" .!= mempty+        <*> o .:? "requested_teams" .!= mempty+        <*> o .: "issue_url"+        <*> o .: "diff_url"+        <*> o .: "url"+        <*> o .: "_links"+        <*> o .:? "merged_at"+        <*> o .: "title"+        <*> o .: "id"++instance ToJSON EditPullRequest where+    toJSON (EditPullRequest t b s base mcm) =+        object $ filter notNull+            [ "title" .= t+            , "body"  .= b+            , "state" .= s+            , "base"  .= base+            , "maintainer_can_modify"+                      .= mcm+            ]+      where+        notNull (_, Null) = False+        notNull (_, _) = True++instance ToJSON CreatePullRequest where+    toJSON (CreatePullRequest t b headPR basePR) =+        object [ "title" .= t, "body" .= b, "head" .= headPR, "base" .= basePR ]+    toJSON (CreatePullRequestIssue issueNum headPR basePR) =+        object [ "issue" .= issueNum, "head" .= headPR, "base" .= basePR]++instance FromJSON PullRequest where+    parseJSON = withObject "PullRequest" $ \o -> PullRequest+        <$> o .:? "closed_at"+        <*> o .: "created_at"+        <*> o .: "user"+        <*> o .: "patch_url"+        <*> o .: "state"+        <*> o .: "number"+        <*> o .: "html_url"+        <*> o .: "updated_at"+        <*> o .:? "body"+        <*> o .: "assignees"+        <*> o .:? "requested_reviewers" .!= mempty+        <*> o .:? "requested_teams" .!= mempty+        <*> o .: "issue_url"+        <*> o .: "diff_url"+        <*> o .: "url"+        <*> o .: "_links"+        <*> o .:? "merged_at"+        <*> o .: "title"+        <*> o .: "id"+        <*> o .:? "merged_by"+        <*> o .: "changed_files"+        <*> o .: "head"+        <*> o .: "comments"+        <*> o .: "deletions"+        <*> o .: "additions"+        <*> o .: "review_comments"+        <*> o .: "base"+        <*> o .: "commits"+        <*> o .: "merged"+        <*> o .:? "mergeable"+        <*> o .: "mergeable_state"++instance FromJSON PullRequestLinks where+    parseJSON = withObject "PullRequestLinks" $ \o -> PullRequestLinks+        <$> fmap getHref (o .: "review_comments")+        <*> fmap getHref (o .: "comments")+        <*> fmap getHref (o .: "html")+        <*> fmap getHref (o .: "self")++instance FromJSON PullRequestCommit where+    parseJSON = withObject "PullRequestCommit" $ \o -> PullRequestCommit+        <$> o .: "label"+        <*> o .: "ref"+        <*> o .: "sha"+        <*> o .: "user"+        <*> o .: "repo"++instance FromJSON PullRequestEvent where+    parseJSON = withObject "PullRequestEvent" $ \o -> PullRequestEvent+        <$> o .: "action"+        <*> o .: "number"+        <*> o .: "pull_request"+        <*> o .: "repository"+        <*> o .: "sender"++instance FromJSON PullRequestEventType where+    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+        <$> o .:? "html_url"+        <*> o .:? "patch_url"+        <*> o .:? "diff_url"++-- Helpers++newtype Href a = Href { getHref :: a }++instance FromJSON a => FromJSON (Href a) where+    parseJSON = withObject "href object" $+        \obj -> Href <$> obj .: "href"++-- | Pull request merge results+data MergeResult+    = MergeSuccessful+    | MergeCannotPerform+    | 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
@@ -0,0 +1,85 @@+module GitHub.Data.Releases where++import GitHub.Data.Definitions+import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++data Release = Release+    { releaseUrl             :: !URL+    , releaseHtmlUrl         :: !URL+    , releaseAssetsurl       :: !URL+    , releaseUploadUrl       :: !URL+    , releaseTarballUrl      :: !URL+    , releaseZipballUrl      :: !URL+    , releaseId              :: !(Id Release)+    , releaseTagName         :: !Text+    , releaseTargetCommitish :: !Text+    , releaseName            :: !Text+    , releaseBody            :: !Text+    , releaseDraft           :: !Bool+    , releasePrerelease      :: !Bool+    , releaseCreatedAt       :: !UTCTime+    , releasePublishedAt     :: !(Maybe UTCTime)+    , releaseAuthor          :: !SimpleUser+    , releaseAssets          :: !(Vector ReleaseAsset)+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON Release where+    parseJSON = withObject "Event" $ \o -> Release+        <$> o .: "url"+        <*> o .: "html_url"+        <*> o .: "assets_url"+        <*> o .: "upload_url"+        <*> o .: "tarball_url"+        <*> o .: "zipball_url"+        <*> o .: "id"+        <*> o .: "tag_name"+        <*> o .: "target_commitish"+        <*> o .: "name"+        <*> o .: "body"+        <*> o .: "draft"+        <*> o .: "prerelease"+        <*> o .: "created_at"+        <*> o .:? "published_at"+        <*> o .: "author"+        <*> o .: "assets"++instance NFData Release+instance Binary Release++data ReleaseAsset = ReleaseAsset+    { releaseAssetUrl                :: !URL+    , releaseAssetBrowserDownloadUrl :: !Text+    , releaseAssetId                 :: !(Id ReleaseAsset)+    , releaseAssetName               :: !Text+    , releaseAssetLabel              :: !(Maybe Text)+    , releaseAssetState              :: !Text+    , releaseAssetContentType        :: !Text+    , releaseAssetSize               :: !Int+    , releaseAssetDownloadCount      :: !Int+    , releaseAssetCreatedAt          :: !UTCTime+    , releaseAssetUpdatedAt          :: !UTCTime+    , releaseAssetUploader           :: !SimpleUser+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON ReleaseAsset where+    parseJSON = withObject "Event" $ \o -> ReleaseAsset+        <$> o .: "url"+        <*> o .: "browser_download_url"+        <*> o .: "id"+        <*> o .: "name"+        <*> o .:? "label"+        <*> o .: "state"+        <*> o .: "content_type"+        <*> o .: "size"+        <*> o .: "download_count"+        <*> o .: "created_at"+        <*> o .: "updated_at"+        <*> o .: "uploader"++instance NFData ReleaseAsset+instance Binary ReleaseAsset
+ src/GitHub/Data/Repos.hs view
@@ -0,0 +1,408 @@+{-# LANGUAGE FlexibleInstances #-}++-- |+-- 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+import GitHub.Data.Id          (Id)+import GitHub.Data.Name        (Name)+import GitHub.Data.Request     (IsPathPart (..))+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.HashMap.Strict as HM+import qualified Data.Text as T+import Data.Aeson.Types (FromJSONKey (..), fromJSONKeyCoerce)++data Repo = Repo+    { repoId              :: !(Id Repo)+    , repoName            :: !(Name Repo)+    , repoOwner           :: !SimpleOwner+    , repoPrivate         :: !Bool+    , repoHtmlUrl         :: !URL+    , repoDescription     :: !(Maybe Text)+    , repoFork            :: !(Maybe Bool)+    , repoUrl             :: !URL+    , repoGitUrl          :: !(Maybe URL)+    , repoSshUrl          :: !(Maybe URL)+    , repoCloneUrl        :: !(Maybe URL)+    , repoHooksUrl        :: !URL+    , repoSvnUrl          :: !(Maybe URL)+    , repoHomepage        :: !(Maybe Text)+    , repoLanguage        :: !(Maybe Language)+    , repoForksCount      :: !Int+    , repoStargazersCount :: !Int+    , repoWatchersCount   :: !Int+    , repoSize            :: !(Maybe Int)+    , repoDefaultBranch   :: !(Maybe Text)+    , repoOpenIssuesCount :: !Int+    , repoHasIssues       :: !(Maybe Bool)+    , repoHasProjects     :: !(Maybe Bool)+    , repoHasWiki         :: !(Maybe Bool)+    , repoHasPages        :: !(Maybe Bool)+    , repoHasDownloads    :: !(Maybe Bool)+    , 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, Eq, Ord, Generic)++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, Eq, Ord, Generic)++instance NFData RepoRef+instance Binary RepoRef++data NewRepo = NewRepo+    { 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+instance Binary NewRepo++newRepo :: Name Repo -> NewRepo+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)+    , 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, Generic)++instance NFData EditRepo+instance Binary EditRepo++-- | Filter the list of the user's repos using any of these constructors.+data RepoPublicity+    = RepoPublicityAll     -- ^ All repos accessible to the user.+    | RepoPublicityOwner   -- ^ Only repos owned by the user.+    | 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, 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, Eq, Ord, Generic)++getLanguage :: Language -> Text+getLanguage (Language l) = l++instance NFData Language+instance Binary Language+instance Hashable Language where+    hashWithSalt salt (Language l) = hashWithSalt salt l+instance IsString Language where+    fromString = Language . fromString++data Contributor+    -- | An existing Github user, with their number of contributions, avatar+    -- URL, login, URL, ID, and Gravatar ID.+    = 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, Eq, Ord, Generic)++instance NFData Contributor+instance Binary Contributor++contributorToSimpleUser :: Contributor -> Maybe SimpleUser+contributorToSimpleUser (AnonymousContributor _ _) = Nothing+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 .: "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 .: "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 .:? "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 .:? "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 .:? "permissions"++instance ToJSON NewRepo where+  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+                   , 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+                   , "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"+        <*> o .: "name"++instance FromJSON Contributor where+    parseJSON = withObject "Contributor" $ \o -> do+        t <- o .: "type"+        case (t :: Text) of+            "Anonymous" -> AnonymousContributor+                <$> o .: "contributions"+                <*> o .: "name"+            _  -> KnownContributor+                <$> o .: "contributions"+                <*> o .: "avatar_url"+                <*> o .: "login"+                <*> o .: "url"+                <*> o .: "id"+                <*> o .: "gravatar_id"++instance FromJSON Language where+    parseJSON = withText "Language" (pure . Language)++instance ToJSON Language where+    toJSON = toJSON . getLanguage++instance FromJSONKey Language where+    fromJSONKey = fromJSONKeyCoerce++data ArchiveFormat+    = ArchiveFormatTarball -- ^ ".tar.gz" format+    | ArchiveFormatZipball -- ^ ".zip" format+    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
@@ -0,0 +1,238 @@+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE GADTs              #-}+{-# LANGUAGE KindSignatures     #-}+{-# LANGUAGE StandaloneDeriving #-}++module GitHub.Data.Request (+    -- * Request+    Request,+    GenRequest (..),+    -- * Smart constructors+    query, pagedQuery, command,+    -- * Auxiliary types+    RW(..),+    CommandMethod(..),+    toMethod,+    FetchCount(..),+    PageParams(..),+    PageLinks(..),+    MediaType (..),+    Paths,+    IsPathPart(..),+    QueryString,+    Count,+    ) where++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.Method as Method+import Network.URI (URI)++------------------------------------------------------------------------------+-- Path parts+------------------------------------------------------------------------------++type Paths = [Text]++class IsPathPart a where+    toPathPart :: a -> Text++instance IsPathPart (Name a) where+    toPathPart = untagName++instance IsPathPart (Id a) where+    toPathPart = T.pack . show . untagId++instance IsPathPart IssueNumber where+    toPathPart = T.pack . show . unIssueNumber++-------------------------------------------------------------------------------+-- Command Method+-------------------------------------------------------------------------------++-- | Http method of requests with body.+data CommandMethod+    = Post+    | Patch+    | Put+    | Delete+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Data, Generic)++instance Hashable CommandMethod++toMethod :: CommandMethod -> Method.Method+toMethod Post   = Method.methodPost+toMethod Patch  = Method.methodPatch+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+    | FetchPage PageParams+    deriving (Eq, Ord, Read, Show, Generic)+++-- | This instance is there mostly for 'fromInteger'.+instance Num FetchCount where+    fromInteger = FetchAtLeast . fromInteger++    FetchAtLeast a + FetchAtLeast b = FetchAtLeast (a * b)+    _ + _                           = FetchAll++    FetchAtLeast a * FetchAtLeast b = FetchAtLeast (a * b)+    _ * _                           = FetchAll++    abs    = error "abs @FetchCount: not implemented"+    signum = error "signum @FetchCount: not implemented"+    negate = error "negate @FetchCount: not implemented"++instance Hashable FetchCount+instance Binary FetchCount+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)++------------------------------------------------------------------------------+-- 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 authenticated/+    | RW  -- ^ /Read-write/, requires authentication+  deriving (Eq, Ord, Read, Show, Enum, Bounded, Data, Generic)++{-+data SRO (rw :: RW) where+    ROO :: SRO 'RO+    ROA :: SRO 'RA++-- | This class is used to describe read-only (but pontentially+class    IReadOnly (rw :: RW) where iro :: SRO rw+instance IReadOnly 'RO        where iro = ROO+instance IReadOnly 'RA        where iro = ROA+-}++-------------------------------------------------------------------------------+-- GitHub Request+-------------------------------------------------------------------------------++-- | Github request data type.+--+-- * @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 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++    -- | Command+    Command+        :: CommandMethod           -- ^ command+        -> Paths                   -- ^ path+        -> LBS.ByteString          -- ^ body+        -> GenRequest mt 'RW a++-- | Most requests ask for @JSON@.+type Request = GenRequest 'MtJSON++-------------------------------------------------------------------------------+-- Smart constructors+-------------------------------------------------------------------------------++query :: Paths -> QueryString -> Request mt a+query ps qs = Query ps qs++pagedQuery :: FromJSON a => Paths -> QueryString -> FetchCount -> Request mt (Vector a)+pagedQuery ps qs fc = PagedQuery ps qs fc++command :: CommandMethod -> Paths -> LBS.ByteString -> Request 'RW a+command m ps body = Command m ps body++-------------------------------------------------------------------------------+-- Instances+-------------------------------------------------------------------------------++deriving instance Eq (GenRequest rw mt a)+deriving instance Ord (GenRequest rw mt a)+deriving instance Show (GenRequest rw mt a)++instance Hashable (GenRequest rw mt a) where+    hashWithSalt salt (Query ps qs) =+        salt `hashWithSalt` (0 :: Int)+             `hashWithSalt` ps+             `hashWithSalt` qs+    hashWithSalt salt (PagedQuery ps qs l) =+        salt `hashWithSalt` (1 :: Int)+             `hashWithSalt` ps+             `hashWithSalt` qs+             `hashWithSalt` l+    hashWithSalt salt (Command m ps body) =+        salt `hashWithSalt` (2 :: Int)+             `hashWithSalt` m+             `hashWithSalt` ps+             `hashWithSalt` body++-- TODO: Binary
+ src/GitHub/Data/Reviews.hs view
@@ -0,0 +1,93 @@+module GitHub.Data.Reviews where++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+    | ReviewStateDismissed+    | ReviewStateCommented+    | ReviewStateChangesRequested+    deriving (Show, Enum, Bounded, Eq, Ord, Generic)++instance NFData ReviewState+instance Binary ReviewState++instance FromJSON ReviewState where+    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 :: !(Maybe UTCTime)+    , reviewPullRequestUrl :: !URL+    , reviewHtmlUrl :: !Text+    , reviewUser :: !SimpleUser+    , reviewId :: !(Id Review)+    } deriving (Show, Generic)++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"++data ReviewComment = ReviewComment+    { reviewCommentId :: !(Id ReviewComment)+    , reviewCommentUser :: !SimpleUser+    , reviewCommentBody :: !Text+    , reviewCommentUrl :: !URL+    , reviewCommentPullRequestReviewId :: !(Id Review)+    , reviewCommentDiffHunk :: !Text+    , reviewCommentPath :: !Text+    , reviewCommentPosition :: !Int+    , reviewCommentOriginalPosition :: !Int+    , reviewCommentCommitId :: !Text+    , reviewCommentOriginalCommitId :: !Text+    , reviewCommentCreatedAt :: !UTCTime+    , reviewCommentUpdatedAt :: !UTCTime+    , reviewCommentHtmlUrl :: !URL+    , reviewCommentPullRequestUrl :: !URL+    } deriving (Show, Generic)++instance NFData ReviewComment+instance Binary ReviewComment++instance FromJSON ReviewComment where+    parseJSON =+        withObject "ReviewComment" $ \o -> ReviewComment+            <$> o .: "id"+            <*> o .: "user"+            <*> o .: "body"+            <*> o .: "url"+            <*> o .: "pull_request_review_id"+            <*> o .: "diff_hunk"+            <*> o .: "path"+            <*> o .: "position"+            <*> o .: "original_position"+            <*> o .: "commit_id"+            <*> o .: "original_commit_id"+            <*> o .: "created_at"+            <*> o .: "updated_at"+            <*> o .: "html_url"+            <*> o .: "pull_request_url"
+ src/GitHub/Data/Search.hs view
@@ -0,0 +1,54 @@+module GitHub.Data.Search where++import GitHub.Data.Repos       (CodeSearchRepo)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Vector as V++data SearchResult' entities = SearchResult+    { searchResultTotalCount :: !Int+    , searchResultResults    :: !entities+    }+  deriving (Show, Data, Eq, Ord, Generic)++type SearchResult entity = SearchResult' (V.Vector entity)++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" .!= 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+    , codeSha     :: !Text+    , codeUrl     :: !URL+    , codeGitUrl  :: !URL+    , codeHtmlUrl :: !URL+    , codeRepo    :: !CodeSearchRepo+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData Code+instance Binary Code++instance FromJSON Code where+    parseJSON = withObject "Code" $ \o -> Code+        <$> o .: "name"+        <*> o .: "path"+        <*> o .: "sha"+        <*> o .: "url"+        <*> o .: "git_url"+        <*> o .: "html_url"+        <*> o .: "repository"
+ src/GitHub/Data/Statuses.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE NoImplicitPrelude  #-}++module GitHub.Data.Statuses where++import GitHub.Data.Definitions+import GitHub.Data.Name        (Name)+import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++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, Eq, Ord, Generic)++instance NFData StatusState+instance Binary StatusState++instance FromJSON StatusState where+    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"+  toJSON StatusSuccess = String "success"+  toJSON StatusError   = String "error"+  toJSON StatusFailure = String "failure"+++data Status = Status+    { statusCreatedAt   :: !UTCTime+    , statusUpdatedAt   :: !UTCTime+    , statusState       :: !StatusState+    , statusTargetUrl   :: !(Maybe URL)+    , statusDescription :: !(Maybe Text)+    , statusId          :: !(Id Status)+    , statusUrl         :: !URL+    , statusContext     :: !(Maybe Text)+    , statusCreator     :: !(Maybe SimpleUser)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON Status where+  parseJSON = withObject "Status" $ \o -> Status+      <$> o .: "created_at"+      <*> o .: "updated_at"+      <*> o .: "state"+      <*> o .:? "target_url"+      <*> o .:? "description"+      <*> o .: "id"+      <*> o .: "url"+      <*> o .:? "context"+      <*> o .:? "creator"+++data NewStatus = NewStatus+    { newStatusState       :: !StatusState+    , newStatusTargetUrl   :: !(Maybe URL)+    , newStatusDescription :: !(Maybe Text)+    , newStatusContext     :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData NewStatus+instance Binary NewStatus++instance ToJSON NewStatus where+    toJSON (NewStatus s t d c) = object $ filter notNull $+        [ "state"       .= s+        , "target_url"  .= t+        , "description" .= d+        , "context"     .= c+        ]+      where+        notNull (_, Null) = False+        notNull (_, _)    = True+++data CombinedStatus = CombinedStatus+    { combinedStatusState      :: !StatusState+    , combinedStatusSha        :: !(Name Commit)+    , combinedStatusTotalCount :: !Int+    , combinedStatusStatuses   :: !(Vector Status)+    , combinedStatusRepository :: !RepoRef+    , combinedStatusCommitUrl  :: !URL+    , combinedStatusUrl        :: !URL+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance FromJSON CombinedStatus where+    parseJSON = withObject "CombinedStatus" $ \o -> CombinedStatus+        <$> o .: "state"+        <*> o .: "sha"+        <*> o .: "total_count"+        <*> o .: "statuses"+        <*> o .: "repository"+        <*> o .: "commit_url"+        <*> o .: "url"
+ src/GitHub/Data/Teams.hs view
@@ -0,0 +1,254 @@+{-# LANGUAGE NoImplicitPrelude  #-}++module GitHub.Data.Teams 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 Privacy+    = PrivacyClosed+    | PrivacySecret+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic)++instance NFData Privacy+instance Binary Privacy++data Permission+    = PermissionPull+    | PermissionPush+    | PermissionAdmin+    deriving (Show, Data, Enum, Bounded, Eq, Ord, Generic)++instance NFData Permission+instance Binary Permission++data AddTeamRepoPermission = AddTeamRepoPermission+    { addTeamRepoPermission :: !Permission+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData AddTeamRepoPermission+instance Binary AddTeamRepoPermission++data SimpleTeam = SimpleTeam+    { simpleTeamId              :: !(Id Team)+    , simpleTeamUrl             :: !URL+    , simpleTeamName            :: !Text  -- TODO (0.15.0): unify this and 'simpleTeamSlug' as in 'Team'.+    , simpleTeamSlug            :: !(Name Team)+    , simpleTeamDescription     :: !(Maybe Text)+    , simpleTeamPrivacy         :: !Privacy+    , simpleTeamPermission      :: !Permission+    , simpleTeamMembersUrl      :: !URL+    , simpleTeamRepositoriesUrl :: !URL+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData SimpleTeam+instance Binary SimpleTeam++data Team = Team+    { teamId              :: !(Id Team)+    , teamUrl             :: !URL+    , teamName            :: !Text+    , teamSlug            :: !(Name Team)+    , teamDescription     :: !(Maybe Text)+    , teamPrivacy         :: !Privacy+    , teamPermission      :: !Permission+    , teamMembersUrl      :: !URL+    , teamRepositoriesUrl :: !URL+    , teamMembersCount    :: !Int+    , teamReposCount      :: !Int+    , teamOrganization    :: !SimpleOrganization+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData Team+instance Binary Team++data CreateTeam = CreateTeam+    { createTeamName        :: !(Name Team)+    , createTeamDescription :: !(Maybe Text)+    , createTeamRepoNames   :: !(Vector (Name Repo))+    , createTeamPrivacy     :: !Privacy+    , createTeamPermission  :: !Permission+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData CreateTeam+instance Binary CreateTeam++data EditTeam = EditTeam+    { editTeamName        :: !(Name Team)+    , editTeamDescription :: !(Maybe Text)+    , editTeamPrivacy     :: !(Maybe Privacy)+    , editTeamPermission  :: !(Maybe Permission)+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData EditTeam+instance Binary  EditTeam++data Role+    = RoleMaintainer+    | RoleMember+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData Role+instance Binary Role++data ReqState+    = StatePending+    | StateActive+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData ReqState+instance Binary ReqState++data TeamMembership = TeamMembership+    { teamMembershipUrl      :: !URL+    , teamMembershipRole     :: !Role+    , teamMembershipReqState :: !ReqState+    }+    deriving (Show, Data, Eq, Ord, Generic)++instance NFData TeamMembership+instance Binary TeamMembership++data CreateTeamMembership = CreateTeamMembership {+  createTeamMembershipRole :: !Role+} deriving (Show, Data, Eq, Ord, Generic)++instance NFData CreateTeamMembership+instance Binary CreateTeamMembership++-- JSON Instances++instance FromJSON SimpleTeam where+    parseJSON = withObject "SimpleTeam" $ \o -> SimpleTeam+        <$> o .: "id"+        <*> o .: "url"+        <*> o .: "name"+        <*> o .: "slug"+        <*> o .:?"description" .!= Nothing+        <*> o .: "privacy"+        <*> o .: "permission"+        <*> o .: "members_url"+        <*> o .: "repositories_url"++instance FromJSON Team where+    parseJSON = withObject "Team" $ \o -> Team+        <$> o .: "id"+        <*> o .: "url"+        <*> o .: "name"+        <*> o .: "slug"+        <*> o .:?"description" .!= Nothing+        <*> o .: "privacy"+        <*> o .: "permission"+        <*> o .: "members_url"+        <*> o .: "repositories_url"+        <*> o .: "members_count"+        <*> o .: "repos_count"+        <*> o .: "organization"++instance ToJSON CreateTeam where+    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 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+        <$> o .: "url"+        <*> o .: "role"+        <*> o .: "state"++instance FromJSON CreateTeamMembership where+    parseJSON = withObject "CreateTeamMembership" $ \o -> CreateTeamMembership+        <$> o .: "role"++instance ToJSON CreateTeamMembership where+    toJSON (CreateTeamMembership { createTeamMembershipRole = role }) =+        object [ "role" .= role ]++instance FromJSON AddTeamRepoPermission where+    parseJSON = withObject "AddTeamRepoPermission" $ \o -> AddTeamRepoPermission+        <$> o .: "permission"++instance ToJSON AddTeamRepoPermission where+    toJSON (AddTeamRepoPermission { addTeamRepoPermission = permission}) =+        object [ "permission" .= permission ]++instance FromJSON Role where+    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 Privacy where+    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" $ \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"+    toJSON StatePending = String "pending"++-- | Filters members returned by their role in the team.+data TeamMemberRole+    = TeamMemberRoleAll         -- ^ all members of the team.+    | TeamMemberRoleMaintainer  -- ^ team maintainers+    | TeamMemberRoleMember      -- ^ normal members of the team.+    deriving (Show, Eq, Ord, Enum, Bounded, Data, Generic)
+ src/GitHub/Data/URL.hs view
@@ -0,0 +1,25 @@+module GitHub.Data.URL (+    URL(..),+    getUrl,+    ) where++import GitHub.Internal.Prelude+import Prelude ()++-- | Data representing URLs in responses.+--+-- /N.B./ syntactical validity is not verified.+newtype URL = URL Text+    deriving (Eq, Ord, Show, Generic, Data)++getUrl :: URL -> Text+getUrl (URL url) = url++instance NFData URL+instance Binary URL++instance ToJSON URL where+    toJSON (URL url) = toJSON url++instance FromJSON URL where+    parseJSON = withText "URL" (pure . URL)
+ src/GitHub/Data/Webhooks.hs view
@@ -0,0 +1,310 @@+module GitHub.Data.Webhooks where++import GitHub.Data.Id          (Id)+import GitHub.Data.URL         (URL)+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Map as M+import qualified Data.Text as T++data RepoWebhook = RepoWebhook+    { repoWebhookUrl          :: !URL+    , repoWebhookTestUrl      :: !URL+    , repoWebhookId           :: !(Id RepoWebhook)+    , repoWebhookName         :: !Text+    , repoWebhookActive       :: !Bool+    , repoWebhookEvents       :: !(Vector RepoWebhookEvent)+    , repoWebhookConfig       :: !(M.Map Text Text)+    , repoWebhookLastResponse :: !RepoWebhookResponse+    , repoWebhookUpdatedAt    :: !UTCTime+    , repoWebhookCreatedAt    :: !UTCTime+    }+  deriving (Show, Data, Eq, Ord, Generic)++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+    | WebhookPullRequestEvent+    | WebhookPullRequestReviewCommentEvent+    | WebhookPullRequestReviewEvent+    | WebhookPushEvent+    | WebhookRegistryPackageEvent+    | WebhookReleaseEvent+    | WebhookRepositoryDispatch+    | WebhookRepositoryEvent+    | WebhookRepositoryImportEvent+    | WebhookRepositoryVulnerabilityAlertEvent+    | WebhookSecretScanningAlert+    | WebhookSecurityAdvisoryEvent+    | WebhookSponsorship+    | WebhookStarEvent+    | WebhookStatusEvent+    | WebhookTeamAddEvent+    | WebhookTeamEvent+    | WebhookWatchEvent+    | WebhookWorkflowDispatch+    | WebhookWorkflowRun+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData RepoWebhookEvent+instance Binary RepoWebhookEvent++data RepoWebhookResponse = RepoWebhookResponse+    { repoWebhookResponseCode    :: !(Maybe Int)+    , repoWebhookResponseStatus  :: !(Maybe Text)+    , repoWebhookResponseMessage :: !(Maybe Text)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData RepoWebhookResponse+instance Binary RepoWebhookResponse++data PingEvent = PingEvent+    { pingEventZen    :: !Text+    , pingEventHook   :: !RepoWebhook+    , pingEventHookId :: !(Id RepoWebhook)+    }+  deriving (Show, Data, Eq, Ord, Generic)++instance NFData PingEvent+instance Binary PingEvent++data NewRepoWebhook = NewRepoWebhook+    { newRepoWebhookName   :: !Text+    , newRepoWebhookConfig :: !(M.Map Text Text)+    , newRepoWebhookEvents :: !(Maybe (Vector RepoWebhookEvent))+    , newRepoWebhookActive :: !(Maybe Bool)+    }+  deriving (Eq, Ord, Show, Data, Generic)++instance NFData NewRepoWebhook+instance Binary NewRepoWebhook++data EditRepoWebhook = EditRepoWebhook+    { editRepoWebhookConfig       :: !(Maybe (M.Map Text Text))+    , editRepoWebhookEvents       :: !(Maybe (Vector RepoWebhookEvent))+    , editRepoWebhookAddEvents    :: !(Maybe (Vector RepoWebhookEvent))+    , editRepoWebhookRemoveEvents :: !(Maybe (Vector RepoWebhookEvent))+    , editRepoWebhookActive       :: !(Maybe Bool)+    }+  deriving (Eq, Ord, Show, Data, Generic)++instance NFData EditRepoWebhook+instance Binary EditRepoWebhook++-- JSON instances++instance FromJSON RepoWebhookEvent where+    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 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+        <$> o .: "url"+        <*> o .: "test_url"+        <*> o .: "id"+        <*> o .: "name"+        <*> o .: "active"+        <*> o .: "events"+        <*> o .: "config"+        <*> o .: "last_response"+        <*> o .: "updated_at"+        <*> o .: "created_at"++instance FromJSON RepoWebhookResponse where+    parseJSON = withObject "RepoWebhookResponse" $ \o -> RepoWebhookResponse+        <$> o .: "code"+        <*> o .:? "status"+        <*> o .:? "message"++instance ToJSON NewRepoWebhook where+  toJSON (NewRepoWebhook { newRepoWebhookName = name+                         , newRepoWebhookConfig = config+                         , newRepoWebhookEvents = events+                         , newRepoWebhookActive = active++             }) = object+             [ "name" .= name+             , "config" .= config+             , "events" .= events+             , "active" .= active+             ]++instance ToJSON EditRepoWebhook where+  toJSON (EditRepoWebhook { editRepoWebhookConfig = config+                          , editRepoWebhookEvents = events+                          , editRepoWebhookAddEvents = addEvents+                          , editRepoWebhookRemoveEvents = removeEvents+                          , editRepoWebhookActive = active+             }) = object+             [ "config" .= config+             , "events" .= events+             , "add_events" .= addEvents+             , "remove_events" .= removeEvents+             , "active" .= active+             ]++instance FromJSON PingEvent where+    parseJSON = withObject "PingEvent" $ \o -> PingEvent+        <$> o .: "zen"+        <*> o .: "hook"+        <*> o .: "hook_id"
+ src/GitHub/Data/Webhooks/Validate.hs view
@@ -0,0 +1,34 @@+-- |+-- Verification of incomming webhook payloads, as described at+-- <https://developer.github.com/webhooks/securing/>++module GitHub.Data.Webhooks.Validate (+  isValidPayload+) where++import GitHub.Internal.Prelude+import Prelude ()++import Crypto.Hash.SHA1 (hmac)+import Data.ByteString  (ByteString)++import qualified Data.ByteString.Base16 as Hex+import qualified Data.Text.Encoding     as TE++-- | Validates a given payload against a given HMAC hexdigest using a given+-- secret.+-- Returns 'True' iff the given hash is non-empty and it's a valid signature of+-- the payload.+isValidPayload+  :: Text           -- ^ the secret+  -> Maybe Text     -- ^ the hash provided by the remote party+                    -- in @X-Hub-Signature@ (if any),+                    -- including the 'sha1=...' prefix+  -> ByteString     -- ^ the body+  -> Bool+isValidPayload secret shaOpt payload = maybe False (sign ==) shaOptBS+  where+    shaOptBS = TE.encodeUtf8 <$> shaOpt+    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
@@ -0,0 +1,25 @@+-- |+-- The events API as described on <https://developer.github.com/v3/activity/events/>.++module GitHub.Endpoints.Activity.Events (+    -- * Events+    repositoryEventsR,+    userEventsR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List repository events.+-- See <https://developer.github.com/v3/activity/events/#list-repository-events>+repositoryEventsR :: Name Owner -> Name Repo -> FetchCount -> Request 'RO (Vector Event)+repositoryEventsR user repo =+    pagedQuery  ["repos", toPathPart user, toPathPart repo, "events"] []++-- | List user public events.+-- See <https://developer.github.com/v3/activity/events/#list-public-events-performed-by-a-user>+userEventsR :: Name User -> FetchCount -> Request 'RO (Vector Event)+userEventsR user =+    pagedQuery ["users", toPathPart user, "events", "public"] []
+ 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
@@ -0,0 +1,54 @@+-- |+-- The repo starring API as described on+-- <https://developer.github.com/v3/activity/starring/>.++module GitHub.Endpoints.Activity.Starring (+    stargazersForR,+    reposStarredByR,+    myStarredR,+    myStarredAcceptStarR,+    starRepoR,+    unstarRepoR,+    module GitHub.Data,+    ) where++import GitHub.Auth+import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | List repositories being starred.+-- See <https://developer.github.com/v3/activity/starring/#list-repositories-being-starred>+reposStarredByR :: Name Owner -> FetchCount -> Request k (Vector Repo)+reposStarredByR user =+    pagedQuery ["users", toPathPart user, "starred"] []++-- | 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.+-- See <https://developer.github.com/v3/activity/starring/#alternative-response-with-star-creation-timestamps-1>+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 -> 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.+-- See <https://developer.github.com/v3/activity/starring/#unstar-a-repository>+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
@@ -0,0 +1,33 @@+-- |+-- The repo watching API as described on+-- <https://developer.github.com/v3/activity/watching/>.++module GitHub.Endpoints.Activity.Watching (+    watchersForR,+    reposWatchedByR,+    unwatchRepoR,+    module GitHub.Data,+) where++import GitHub.Auth+import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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++-- | 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
@@ -0,0 +1,47 @@+-- |+-- The gists API as described at <http://developer.github.com/v3/gists/>.++module GitHub.Endpoints.Gists (+    gistsR,+    gistR,+    createGistR,+    starGistR,+    unstarGistR,+    deleteGistR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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] []++-- | 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 -> 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 -> 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 -> GenRequest 'MtUnit 'RW ()+deleteGistR gid = Command Delete ["gists", toPathPart gid] mempty
+ src/GitHub/Endpoints/Gists/Comments.hs view
@@ -0,0 +1,25 @@+-- |+-- The loving comments people have left on Gists, described on+-- <http://developer.github.com/v3/gists/comments/>.++module GitHub.Endpoints.Gists.Comments (+    commentsOnR,+    gistCommentR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | Query a single comment.+-- See <https://developer.github.com/v3/gists/comments/#get-a-single-comment>+gistCommentR :: Id GistComment -> Request k GistComment+gistCommentR cid =+    query ["gists", "comments", toPathPart cid] []
+ src/GitHub/Endpoints/GitData/Blobs.hs view
@@ -0,0 +1,17 @@+-- |+-- 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 (+    blobR,+    module GitHub.Data,+    ) where++import GitHub.Data+import Prelude ()++-- | Query a blob.+-- See <https://developer.github.com/v3/git/blobs/#get-a-blob>+blobR :: Name Owner -> Name Repo -> Name Blob -> Request k Blob+blobR user repo sha =+    query ["repos", toPathPart user, toPathPart repo, "git", "blobs", toPathPart sha] []
+ src/GitHub/Endpoints/GitData/Commits.hs view
@@ -0,0 +1,17 @@+-- |+-- 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 (+    gitCommitR,+    module GitHub.Data,+) where++import GitHub.Data+import Prelude ()++-- | Query a commit.+-- See <https://developer.github.com/v3/git/commits/#get-a-commit>+gitCommitR :: Name Owner -> Name Repo -> Name GitCommit -> Request k GitCommit+gitCommitR user repo sha =+    query ["repos", toPathPart user, toPathPart repo, "git", "commits", toPathPart sha] []
+ src/GitHub/Endpoints/GitData/References.hs view
@@ -0,0 +1,47 @@+-- |+-- 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 (+    referenceR,+    referencesR,+    createReferenceR,+    deleteReferenceR,+    namespacedReferencesR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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] []++-- | Query all References.+-- See <https://developer.github.com/v3/git/refs/#get-all-references>+referencesR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector GitReference)+referencesR user repo =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "git", "refs"] []++-- | 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)++-- | 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>+namespacedReferencesR :: Name Owner -> Name Repo -> Text -> Request k [GitReference]+namespacedReferencesR user repo namespace =+    query ["repos", toPathPart user, toPathPart repo, "git", "refs", namespace] []
+ src/GitHub/Endpoints/GitData/Trees.hs view
@@ -0,0 +1,25 @@+-- |+-- 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 (+    treeR,+    nestedTreeR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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] []++-- | Query a Tree Recursively.+-- See <https://developer.github.com/v3/git/trees/#get-a-tree-recursively>+nestedTreeR :: Name Owner -> Name Repo -> Name Tree -> Request k Tree+nestedTreeR user repo sha =+    query  ["repos", toPathPart user, toPathPart repo, "git", "trees", toPathPart sha] [("recursive", Just "1")]
+ src/GitHub/Endpoints/Issues.hs view
@@ -0,0 +1,64 @@+-- |+-- The issues API as described on <http://developer.github.com/v3/issues/>.++module GitHub.Endpoints.Issues (+    currentUserIssuesR,+    organizationIssuesR,+    issueR,+    issuesForRepoR,+    createIssueR,+    newIssue,+    editIssueR,+    editOfIssue,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | See <https://developer.github.com/v3/issues/#list-issues>.+currentUserIssuesR :: IssueMod -> FetchCount -> Request 'RA (Vector Issue)+currentUserIssuesR opts =+    pagedQuery ["user", "issues"] (issueModToQueryString opts)++-- | See <https://developer.github.com/v3/issues/#list-issues>.+organizationIssuesR :: Name Organization -> IssueMod -> FetchCount -> Request k (Vector Issue)+organizationIssuesR org opts =+    pagedQuery ["orgs", toPathPart org, "issues"] (issueModToQueryString opts)++-- | Query a single issue.+-- See <https://developer.github.com/v3/issues/#get-a-single-issue>+issueR :: Name Owner -> Name Repo -> IssueNumber -> Request k Issue+issueR user reqRepoName reqIssueNumber =+    query ["repos", toPathPart user, toPathPart reqRepoName, "issues", toPathPart reqIssueNumber] []++-- | 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)+issuesForRepoR user reqRepoName opts =+    pagedQuery ["repos", toPathPart user, toPathPart reqRepoName, "issues"] qs+  where+    qs = issueRepoModToQueryString opts++-- Creating new issues.++newIssue :: Text -> NewIssue+newIssue title = NewIssue title Nothing mempty Nothing Nothing++-- | Create an issue.+-- See <https://developer.github.com/v3/issues/#create-an-issue>+createIssueR :: Name Owner -> Name Repo -> NewIssue -> Request 'RW Issue+createIssueR user repo =+    command Post ["repos", toPathPart user, toPathPart repo, "issues"] . encode++-- Editing issues.++editOfIssue :: EditIssue+editOfIssue = EditIssue Nothing Nothing Nothing Nothing Nothing Nothing++-- | Edit an issue.+-- See <https://developer.github.com/v3/issues/#edit-an-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
@@ -0,0 +1,52 @@+-- |+-- The Github issue comments API from+-- <http://developer.github.com/v3/issues/comments/>.++module GitHub.Endpoints.Issues.Comments (+    commentR,+    commentsR,+    createCommentR,+    deleteCommentR,+    editCommentR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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] []++-- | List comments on an issue.+-- See <https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue>+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 comment.+-- See <https://developer.github.com/v3/issues/comments/#create-a-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.+-- 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 =+    command Patch parts (encode $ EditComment body)+  where+    parts = ["repos", toPathPart user, toPathPart repo, "issues", "comments", toPathPart commid]++-- | Delete a comment.+-- See <https://developer.github.com/v3/issues/comments/#delete-a-comment>+deleteCommentR :: Name Owner -> Name Repo -> Id Comment -> GenRequest 'MtUnit 'RW ()+deleteCommentR user repo commid =+    Command Delete parts mempty+  where+    parts = ["repos", toPathPart user, toPathPart repo, "issues", "comments", toPathPart commid]
+ src/GitHub/Endpoints/Issues/Events.hs view
@@ -0,0 +1,32 @@+-- |+-- The Github issue events API, which is described on+-- <http://developer.github.com/v3/issues/events/>++module GitHub.Endpoints.Issues.Events (+    eventsForIssueR,+    eventsForRepoR,+    eventR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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"] []++-- | Query a single event.+-- See <https://developer.github.com/v3/issues/events/#get-a-single-event>+eventR :: Name Owner -> Name Repo -> Id IssueEvent -> Request k IssueEvent+eventR user repo eid =+    query ["repos", toPathPart user, toPathPart repo, "issues", "events", toPathPart eid] []
+ src/GitHub/Endpoints/Issues/Labels.hs view
@@ -0,0 +1,108 @@+-- |+-- The API for dealing with labels on Github issues as described on+-- <http://developer.github.com/v3/issues/labels/>.++module GitHub.Endpoints.Issues.Labels (+    labelsOnRepoR,+    labelR,+    createLabelR,+    updateLabelR,+    deleteLabelR,+    labelsOnIssueR,+    addLabelsToIssueR,+    removeLabelFromIssueR,+    replaceAllLabelsForIssueR,+    removeAllLabelsFromIssueR,+    labelsOnMilestoneR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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.+-- See <https://developer.github.com/v3/issues/labels/#create-a-label>+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+             -> UpdateIssueLabel   -- ^ new label+             -> Request 'RW IssueLabel+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 -> GenRequest 'MtUnit 'RW ()+deleteLabelR user repo lbl =+    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>+labelsOnIssueR :: Name Owner -> Name Repo -> Id Issue -> FetchCount -> Request k (Vector IssueLabel)+labelsOnIssueR user repo iid =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"] []++-- | Add lables to an issue.+-- See <https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue>+addLabelsToIssueR :: Foldable f+                  => Name Owner+                  -> Name Repo+                  -> Id Issue+                  -> f (Name IssueLabel)+                  -> Request 'RW (Vector IssueLabel)+addLabelsToIssueR user repo iid lbls =+    command Post paths (encode $ toList lbls)+  where+    paths = ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"]++-- | 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 -> 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.+-- See <https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue>+--+-- Sending an empty list will remove all labels from the issue.+replaceAllLabelsForIssueR :: Foldable f+                          => Name Owner+                          -> Name Repo+                          -> Id Issue+                          -> f (Name IssueLabel)+                          -> Request 'RW (Vector IssueLabel)+replaceAllLabelsForIssueR user repo iid lbls =+    command Put paths (encode $ toList lbls)+  where+    paths = ["repos", toPathPart user, toPathPart repo, "issues", toPathPart iid, "labels"]++-- | 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 -> GenRequest 'MtUnit 'RW ()+removeAllLabelsFromIssueR user repo iid =+    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>+labelsOnMilestoneR :: Name Owner -> Name Repo -> Id Milestone -> FetchCount -> Request k (Vector IssueLabel)+labelsOnMilestoneR user repo mid =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "milestones", toPathPart mid, "labels"] []
+ src/GitHub/Endpoints/Issues/Milestones.hs view
@@ -0,0 +1,47 @@+-- |+-- The milestones API as described on+-- <http://developer.github.com/v3/issues/milestones/>.++module GitHub.Endpoints.Issues.Milestones (+    milestonesR,+    milestoneR,+    createMilestoneR,+    updateMilestoneR,+    deleteMilestoneR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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
@@ -0,0 +1,28 @@+-- |+-- The orgs API as described on <http://developer.github.com/v3/orgs/>.++module GitHub.Endpoints.Organizations (+    publicOrganizationsForR,+    publicOrganizationR,+    organizationsR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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 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"] []++-- | Query an organization.+-- See <https://developer.github.com/v3/orgs/#get-an-organization>+publicOrganizationR :: Name Organization -> Request k Organization+publicOrganizationR reqOrganizationName = query ["orgs", toPathPart reqOrganizationName] []
+ src/GitHub/Endpoints/Organizations/Members.hs view
@@ -0,0 +1,58 @@+-- |+-- The organization members API as described on+-- <http://developer.github.com/v3/orgs/members/>.++module GitHub.Endpoints.Organizations.Members (+    membersOfR,+    membersOfWithR,+    isMemberOfR,+    orgInvitationsR,+    orgMembershipR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | All the users who are members of the specified organization.+--+-- See <https://developer.github.com/v3/orgs/members/#members-list>+membersOfR :: Name Organization -> FetchCount -> Request k (Vector SimpleUser)+membersOfR organization =+    pagedQuery ["orgs", toPathPart organization, "members"] []++-- | 'membersOfR' with filters.+--+-- See <https://developer.github.com/v3/orgs/members/#members-list>+membersOfWithR :: Name Organization -> OrgMemberFilter -> OrgMemberRole -> FetchCount -> Request k (Vector SimpleUser)+membersOfWithR org f r =+    pagedQuery ["orgs", toPathPart org, "members"] [("filter", Just f'), ("role", Just r')]+  where+    f' = case f of+        OrgMemberFilter2faDisabled -> "2fa_disabled"+        OrgMemberFilterAll         -> "all"+    r' = case r of+        OrgMemberRoleAll    -> "all"+        OrgMemberRoleAdmin  -> "admin"+        OrgMemberRoleMember -> "member"++-- | 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 -> GenRequest 'MtStatus rw Bool+isMemberOfR user org =+    Query [ "orgs", toPathPart org, "members", toPathPart user ] []++-- | List pending organization invitations+--+-- 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
@@ -0,0 +1,101 @@+-- |+-- The Owner teams API as described on+-- <http://developer.github.com/v3/orgs/teams/>.++module GitHub.Endpoints.Organizations.Teams (+    teamsOfR,+    teamInfoForR,+    createTeamForR,+    editTeamR,+    deleteTeamR,+    listTeamMembersR,+    listTeamReposR,+    addOrUpdateTeamRepoR,+    teamMembershipInfoForR,+    addTeamMembershipForR,+    deleteTeamMembershipForR,+    listTeamsCurrentR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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 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 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)++--+-- See <https://developer.github.com/v3/orgs/teams/#delete-team>+deleteTeamR :: Id Team -> GenRequest 'MtUnit 'RW ()+deleteTeamR tid =+    Command Delete ["teams", toPathPart tid] mempty++-- | List team members.+--+-- See <https://developer.github.com/v3/orgs/teams/#list-team-members>+listTeamMembersR :: Id Team -> TeamMemberRole -> FetchCount -> Request 'RA (Vector SimpleUser)+listTeamMembersR tid r =+    pagedQuery ["teams", toPathPart tid, "members"] [("role", Just r')]+  where+    r' = case r of+        TeamMemberRoleAll         -> "all"+        TeamMemberRoleMaintainer  -> "maintainer"+        TeamMemberRoleMember      -> "member"++-- | 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"] []++-- | 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 -> GenRequest 'MtUnit 'RW ()+addOrUpdateTeamRepoR tid org repo permission =+    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+teamMembershipInfoForR :: Id Team -> Name Owner -> Request k TeamMembership+teamMembershipInfoForR tid user =+    query ["teams", toPathPart tid, "memberships", toPathPart user] []++-- | 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)++-- | Remove team membership.+-- See <https://developer.github.com/v3/orgs/teams/#remove-team-membership>+deleteTeamMembershipForR :: Id Team -> Name Owner -> GenRequest 'MtUnit 'RW ()+deleteTeamMembershipForR tid user =+    Command Delete ["teams", toPathPart tid, "memberships", toPathPart user] mempty++-- | List user teams.+-- See <https://developer.github.com/v3/orgs/teams/#list-user-teams>+listTeamsCurrentR :: FetchCount -> Request 'RA (Vector Team)+listTeamsCurrentR =+    pagedQuery ["user", "teams"] []
+ src/GitHub/Endpoints/PullRequests.hs view
@@ -0,0 +1,101 @@+-- |+-- The pull requests API as documented at+-- <http://developer.github.com/v3/pulls/>.++module GitHub.Endpoints.PullRequests (+    pullRequestsForR,+    pullRequestR,+    pullRequestDiffR,+    pullRequestPatchR,+    createPullRequestR,+    updatePullRequestR,+    pullRequestCommitsR,+    pullRequestFilesR,+    isPullRequestMergedR,+    mergePullRequestR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()+import Data.ByteString.Lazy (ByteString)++-- | List pull requests.+-- See <https://developer.github.com/v3/pulls/#list-pull-requests>+pullRequestsForR+    :: Name Owner+    -> Name Repo+    -> PullRequestMod+    -> FetchCount+    -> Request k (Vector SimplePullRequest)+pullRequestsForR user repo opts = pagedQuery+    ["repos", toPathPart user, toPathPart repo, "pulls"]+    (prModToQueryString opts)++-- | 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] []++-- | 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 -> IssueNumber -> Request k PullRequest+pullRequestR user repo prid =+    query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] []++-- | Create a pull request.+-- See <https://developer.github.com/v3/pulls/#create-a-pull-request>+createPullRequestR :: Name Owner+                   -> Name Repo+                   -> CreatePullRequest+                   -> Request 'RW PullRequest+createPullRequestR user repo cpr =+    command Post ["repos", toPathPart user, toPathPart repo, "pulls"] (encode cpr)++-- | Update a pull request.+-- See <https://developer.github.com/v3/pulls/#update-a-pull-request>+updatePullRequestR :: Name Owner+                   -> Name Repo+                   -> IssueNumber+                   -> EditPullRequest+                   -> Request 'RW PullRequest+updatePullRequestR user repo prid epr =+    command Patch ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid] (encode epr)++-- | List commits on a pull request.+-- See <https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request>+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"] []++-- | List pull requests files.+-- See <https://developer.github.com/v3/pulls/#list-pull-requests-files>+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"] []++-- | 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 -> IssueNumber -> GenRequest 'MtStatus rw Bool+isPullRequestMergedR user repo prid =+    Query ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "merge"] []++-- | Merge a pull request (Merge Button).+-- https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button+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"]++    buildCommitMessageMap :: Maybe Text -> Value+    buildCommitMessageMap (Just msg) = object ["commit_message" .= msg ]+    buildCommitMessageMap Nothing    = object []
+ src/GitHub/Endpoints/PullRequests/Comments.hs view
@@ -0,0 +1,46 @@+-- |+-- The pull request review comments API as described at+-- <http://developer.github.com/v3/pulls/comments/>.++module GitHub.Endpoints.PullRequests.Comments (+    pullRequestCommentsR,+    pullRequestCommentR,+    createPullCommentR,+    createPullCommentReplyR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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 -> IssueNumber -> FetchCount -> Request k (Vector Comment)+pullRequestCommentsR user repo prid =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "pulls", toPathPart prid, "comments"] []++-- | 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
@@ -0,0 +1,73 @@+-- |+-- The reviews API as described on <http://developer.github.com/v3/pulls/reviews/>.++module GitHub.Endpoints.PullRequests.Reviews+    ( pullRequestReviewsR+    , pullRequestReviewR+    , pullRequestReviewCommentsR+    , module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List reviews for a pull request.+-- See <https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request>+pullRequestReviewsR+    :: Name Owner+    -> Name Repo+    -> IssueNumber+    -> FetchCount+    -> Request k (Vector Review)+pullRequestReviewsR owner repo prid =+    pagedQuery+        [ "repos"+        , toPathPart owner+        , toPathPart repo+        , "pulls"+        , toPathPart prid+        , "reviews"+        ]+        []++-- | Query a single pull request review.+-- see <https://developer.github.com/v3/pulls/reviews/#get-a-single-review>+pullRequestReviewR+    :: Name Owner+    -> Name Repo+    -> IssueNumber+    -> Id Review+    -> Request k Review+pullRequestReviewR owner repo prid rid =+    query+        [ "repos"+        , toPathPart owner+        , toPathPart repo+        , "pulls"+        , toPathPart prid+        , "reviews"+        , toPathPart 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+    -> IssueNumber+    -> Id Review+    -> Request k [ReviewComment]+pullRequestReviewCommentsR owner repo prid rid =+    query+        [ "repos"+        , toPathPart owner+        , toPathPart repo+        , "pulls"+        , toPathPart prid+        , "reviews"+        , toPathPart rid+        , "comments"+        ]+        []
+ 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
@@ -0,0 +1,140 @@+-- |+-- The Github Repos API, as documented at+-- <http://developer.github.com/v3/repos/>++module GitHub.Endpoints.Repos (+    -- * Querying repositories+    currentUserReposR,+    userReposR,+    organizationReposR,+    repositoryR,+    contributorsR,+    languagesForR,+    tagsForR,+    branchesForR,++    -- ** Create+    createRepoR,+    createOrganizationRepoR,+    forkExistingRepoR,++    -- ** Edit+    editRepoR,++    -- ** Delete+    deleteRepoR,++    -- * Data+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++repoPublicityQueryString :: RepoPublicity -> QueryString+repoPublicityQueryString RepoPublicityAll     = [("type", Just "all")]+repoPublicityQueryString RepoPublicityOwner   = [("type", Just "owner")]+repoPublicityQueryString RepoPublicityMember  = [("type", Just "member")]+repoPublicityQueryString RepoPublicityPublic  = [("type", Just "public")]+repoPublicityQueryString RepoPublicityPrivate = [("type", Just "private")]++-- | 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++-- | 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++-- | List organization repositories.+-- See <https://docs.github.com/en/rest/reference/repos#list-organization-repositories>+organizationReposR+    :: Name Organization+    -> RepoPublicity+    -> FetchCount+    -> Request k (Vector Repo)+organizationReposR org publicity =+    pagedQuery ["orgs", toPathPart org, "repos"] qs+  where+    qs = repoPublicityQueryString publicity++-- | Query single repository.+-- See <https://developer.github.com/v3/repos/#get>+repositoryR :: Name Owner -> Name Repo -> Request k Repo+repositoryR user repo =+    query ["repos", toPathPart user, toPathPart repo] []++-- | Create a new repository.+-- See <https://developer.github.com/v3/repos/#create>+createRepoR :: NewRepo -> Request 'RW Repo+createRepoR nrepo =+    command Post ["user", "repos"] (encode nrepo)++-- | Fork an existing repository.+-- See <https://developer.github.com/v3/repos/forks/#create-a-fork>+-- TODO: The third paramater (an optional Organisation) is not used yet.+forkExistingRepoR :: Name Owner -> Name Repo -> Maybe (Name Owner) -> Request 'RW Repo+forkExistingRepoR owner repo _morg =+    command Post ["repos", toPathPart owner, toPathPart repo, "forks" ] mempty++-- | 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.+-- See <https://developer.github.com/v3/repos/#edit>+editRepoR :: Name Owner -> Name Repo -> EditRepo -> Request 'RW Repo+editRepoR user repo body =+    command Patch ["repos", toPathPart user, toPathPart repo] (encode b)+  where+    -- if no name is given, use curent name+    b = body {editName = editName body <|> Just repo}++-- | List contributors.+-- See <https://developer.github.com/v3/repos/#list-contributors>+contributorsR+    :: Name Owner+    -> Name Repo+    -> Bool              -- ^ Include anonymous+    -> FetchCount+    -> Request k (Vector Contributor)+contributorsR user repo anon =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "contributors"] qs+  where+    qs | anon      = [("anon", Just "true")]+       | otherwise = []++-- | 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"] []++-- | 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"] []++-- | 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 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
+ src/GitHub/Endpoints/Repos/Collaborators.hs view
@@ -0,0 +1,51 @@+-- |+-- The repo collaborators API as described on+-- <http://developer.github.com/v3/repos/collaborators/>.++module GitHub.Endpoints.Repos.Collaborators (+    collaboratorsOnR,+    collaboratorPermissionOnR,+    isCollaboratorOnR,+    addCollaboratorR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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 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>+isCollaboratorOnR+    :: Name Owner  -- ^ Repository owner+    -> Name Repo         -- ^ Repository name+    -> Name User         -- ^ Collaborator?+    -> 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
@@ -0,0 +1,32 @@+-- |+-- The repo commits API as described on+-- <http://developer.github.com/v3/repos/comments/>.++module GitHub.Endpoints.Repos.Comments (+    commentsForR,+    commitCommentsForR,+    commitCommentForR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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"] []++-- | Query a single commit comment.+-- See <https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment>+commitCommentForR :: Name Owner -> Name Repo -> Id Comment -> Request k Comment+commitCommentForR user repo cid =+    query ["repos", toPathPart user, toPathPart repo, "comments", toPathPart cid] []
+ src/GitHub/Endpoints/Repos/Commits.hs view
@@ -0,0 +1,52 @@+-- |+-- The repo commits API as described on+-- <http://developer.github.com/v3/repos/commits/>.++module GitHub.Endpoints.Repos.Commits (+    CommitQueryOption(..),+    commitsForR,+    commitsWithOptionsForR,+    commitR,+    diffR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.ByteString    as BS+import qualified Data.Text          as T+import qualified Data.Text.Encoding as TE++renderCommitQueryOption :: CommitQueryOption -> (BS.ByteString, Maybe BS.ByteString)+renderCommitQueryOption (CommitQuerySha sha)      = ("sha", Just $ TE.encodeUtf8 sha)+renderCommitQueryOption (CommitQueryPath path)     = ("path", Just $ TE.encodeUtf8 path)+renderCommitQueryOption (CommitQueryAuthor author) = ("author", Just $ TE.encodeUtf8 author)+renderCommitQueryOption (CommitQuerySince date)    = ("since", Just $ TE.encodeUtf8 . T.pack $ formatISO8601 date)+renderCommitQueryOption (CommitQueryUntil date)    = ("until", Just $ TE.encodeUtf8 . T.pack $ formatISO8601 date)++-- | 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 []++-- | 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)+commitsWithOptionsForR user repo limit opts =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "commits"] qs limit+  where+    qs = map renderCommitQueryOption opts++-- | 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] []++-- | Compare two commits.+-- See <https://developer.github.com/v3/repos/commits/#compare-two-commits>+diffR :: Name Owner -> Name Repo -> Name Commit -> Name Commit -> Request k Diff+diffR user repo base headref =+    query ["repos", toPathPart user, toPathPart repo, "compare", toPathPart base <> "..." <> toPathPart headref] []
+ src/GitHub/Endpoints/Repos/Contents.hs view
@@ -0,0 +1,86 @@+-- |+-- The Github Repo Contents API, as documented at+-- <https://developer.github.com/v3/repos/contents/>++module GitHub.Endpoints.Repos.Contents (+    -- * Querying contents+    contentsForR,+    readmeForR,+    archiveForR,++    -- ** Create+    createFileR,++    -- ** Update+    updateFileR,++    -- ** Delete+    deleteFileR,++    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++import Data.Maybe (maybeToList)+import qualified Data.Text.Encoding as TE+import Network.URI (URI)++contentsForR+    :: Name Owner+    -> Name Repo+    -> Text            -- ^ file or directory+    -> Maybe Text      -- ^ Git commit+    -> Request k Content+contentsForR user repo path ref =+    query ["repos", toPathPart user, toPathPart repo, "contents", path] qs+  where+    qs =  maybe [] (\r -> [("ref", Just . TE.encodeUtf8 $ r)]) ref++readmeForR :: Name Owner -> Name Repo -> Request k Content+readmeForR user repo =+    query ["repos", toPathPart user, toPathPart repo, "readme"] []++-- | 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+    -> 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.+-- See <https://developer.github.com/v3/repos/contents/#create-a-file>+createFileR+    :: Name Owner+    -> Name Repo+    -> CreateFile+    -> Request 'RW ContentResult+createFileR user repo body =+    command Put ["repos", toPathPart user, toPathPart repo, "contents", createFilePath body] (encode body)++-- | Update a file.+-- See <https://developer.github.com/v3/repos/contents/#update-a-file>+updateFileR+    :: Name Owner+    -> Name Repo+    -> UpdateFile+    -> Request 'RW ContentResult+updateFileR user repo body =+    command Put ["repos", toPathPart user, toPathPart repo, "contents", updateFilePath body] (encode body)++-- | Delete a file.+-- See <https://developer.github.com/v3/repos/contents/#delete-a-file>+deleteFileR+    :: Name Owner+    -> Name Repo+    -> DeleteFile+    -> GenRequest 'MtUnit 'RW ()+deleteFileR user repo body =+    Command Delete ["repos", toPathPart user, toPathPart repo, "contents", deleteFilePath body] (encode body)
+ src/GitHub/Endpoints/Repos/DeployKeys.hs view
@@ -0,0 +1,46 @@+-----------------------------------------------------------------------------+-- |+-- License     :  BSD-3-Clause+-- Maintainer  :  Todd Mohney <toddmohney@gmail.com>+--+-- The deploy keys API, as described at+-- <https://developer.github.com/v3/repos/keys>+module GitHub.Endpoints.Repos.DeployKeys (+    -- * Querying deploy keys+    deployKeysForR,+    deployKeyForR,++    -- ** Create+    createRepoDeployKeyR,++    -- ** Delete+    deleteRepoDeployKeyR,+) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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.+-- 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.+-- 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)++-- | Delete a deploy key.+-- See <https://developer.github.com/v3/repos/keys/#remove-a-deploy-key>+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
+ 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
@@ -0,0 +1,18 @@+-- |+-- Hot forking action, as described at+-- <http://developer.github.com/v3/repos/forks/>.++module GitHub.Endpoints.Repos.Forks (+    forksForR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | List forks.+-- See <https://developer.github.com/v3/repos/forks/#list-forks>+forksForR :: Name Owner -> Name Repo -> FetchCount -> Request k (Vector Repo)+forksForR user repo =+    pagedQuery ["repos", toPathPart user, toPathPart repo, "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
@@ -0,0 +1,49 @@+-- The Release API, as described at+-- <https://developer.github.com/v3/repos/releases/>.+module GitHub.Endpoints.Repos.Releases (+    releasesR,+    releaseR,+    latestReleaseR,+    releaseByTagNameR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | 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 ] []++-- | 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" ] []++-- | Get a release by tag name+-- See <https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name>+releaseByTagNameR :: Name Owner -> Name Repo -> Text -> Request k Release+releaseByTagNameR user repo reqTagName =+    query ["repos", toPathPart user, toPathPart repo, "releases", "tags" , reqTagName ] []++{-+--  TODO: implement the following:+    https://developer.github.com/v3/repos/releases/#create-a-release+    https://developer.github.com/v3/repos/releases/#edit-a-release+    https://developer.github.com/v3/repos/releases/#delete-a-release+    https://developer.github.com/v3/repos/releases/#list-assets-for-a-release+    https://developer.github.com/v3/repos/releases/#upload-a-release-asset+    https://developer.github.com/v3/repos/releases/#get-a-single-release-asset+    https://developer.github.com/v3/repos/releases/#edit-a-release-asset+    https://developer.github.com/v3/repos/releases/#delete-a-release-asset+-}
+ src/GitHub/Endpoints/Repos/Statuses.hs view
@@ -0,0 +1,34 @@+-- |+-- The repo statuses API as described on+-- <https://developer.github.com/v3/repos/statuses/>.++module GitHub.Endpoints.Repos.Statuses (+    createStatusR,+    statusesForR,+    statusForR,+    module GitHub.Data+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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 =+    command Post parts . encode+    where+        parts = ["repos", toPathPart owner, toPathPart repo, "statuses", toPathPart sha]++-- | 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+-- See <https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref>+statusForR :: Name Owner -> Name Repo -> Name Commit -> Request 'RW CombinedStatus+statusForR user repo sha =+    query ["repos", toPathPart user, toPathPart repo, "commits", toPathPart sha, "status"] []
+ src/GitHub/Endpoints/Repos/Webhooks.hs view
@@ -0,0 +1,75 @@+-- |+-- 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+    webhooksForR,+    webhookForR,++    -- ** Create+    createRepoWebhookR,++    -- ** Edit+    editRepoWebhookR,++    -- ** Test+    testPushRepoWebhookR,+    pingRepoWebhookR,++    -- ** Delete+    deleteRepoWebhookR,+) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []+-- 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] []++-- | 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)++-- | 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)++-- | Test a push hook.+-- See <https://developer.github.com/v3/repos/hooks/#test-a-push-hook>+testPushRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtStatus 'RW Bool+testPushRepoWebhookR user repo hookId =+    Command Post (createWebhookOpPath user repo hookId $ Just "tests") (encode ())++-- | Ping a hook.+-- See <https://developer.github.com/v3/repos/hooks/#ping-a-hook>+pingRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtStatus 'RW Bool+pingRepoWebhookR user repo hookId =+    Command Post (createWebhookOpPath user repo hookId $ Just "pings") (encode ())++-- | Delete a hook.+-- See <https://developer.github.com/v3/repos/hooks/#delete-a-hook>+deleteRepoWebhookR :: Name Owner -> Name Repo -> Id RepoWebhook -> GenRequest 'MtUnit 'RW ()+deleteRepoWebhookR user repo hookId =+    Command Delete (createWebhookOpPath user repo hookId Nothing) mempty++createBaseWebhookPath :: Name Owner -> Name Repo -> Id RepoWebhook -> Paths+createBaseWebhookPath user repo hookId =+    ["repos", toPathPart user, toPathPart repo, "hooks", toPathPart hookId]++createWebhookOpPath :: Name Owner -> Name Repo -> Id RepoWebhook -> Maybe Text -> Paths+createWebhookOpPath owner reqName webhookId Nothing = createBaseWebhookPath owner reqName webhookId+createWebhookOpPath owner reqName webhookId (Just operation) = createBaseWebhookPath owner reqName webhookId ++ [operation]
+ src/GitHub/Endpoints/Search.hs view
@@ -0,0 +1,41 @@+-- |+-- The Github Search API, as described at+-- <http://developer.github.com/v3/search/>.++module GitHub.Endpoints.Search(+    searchReposR,+    searchCodeR,+    searchIssuesR,+    searchUsersR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++import qualified Data.Text.Encoding as TE++-- | Search repositories.+-- See <https://developer.github.com/v3/search/#search-repositories>+searchReposR :: Text -> FetchCount -> Request k (SearchResult Repo)+searchReposR searchString =+    PagedQuery ["search", "repositories"] [("q", Just $ TE.encodeUtf8 searchString)]++-- | Search code.+-- See <https://developer.github.com/v3/search/#search-code>+searchCodeR :: Text -> FetchCount -> Request k (SearchResult Code)+searchCodeR searchString =+    PagedQuery ["search", "code"] [("q", Just $ TE.encodeUtf8 searchString)]++-- | Search issues.+-- See <https://developer.github.com/v3/search/#search-issues>+searchIssuesR :: Text -> FetchCount -> Request k (SearchResult Issue)+searchIssuesR 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
@@ -0,0 +1,35 @@+-- |+-- The Github Users API, as described at+-- <http://developer.github.com/v3/users/>.++module GitHub.Endpoints.Users (+    userInfoForR,+    ownerInfoForR,+    userInfoCurrentR,+    module GitHub.Data,+    ) where++import GitHub.Data+import Prelude ()++-- | 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] []++-- | Query a single user or an organization.+-- See <https://developer.github.com/v3/users/#get-a-single-user>+ownerInfoForR :: Name Owner -> Request k Owner+ownerInfoForR owner = query ["users", toPathPart owner] []++-- | Query the authenticated user.+-- See <https://developer.github.com/v3/users/#get-the-authenticated-user>+userInfoCurrentR :: Request 'RA User+userInfoCurrentR = query ["user"] []
+ src/GitHub/Endpoints/Users/Emails.hs view
@@ -0,0 +1,25 @@+-- |+-- The user emails API as described on+-- <http://developer.github.com/v3/users/emails/>.++module GitHub.Endpoints.Users.Emails (+    currentUserEmailsR,+    currentUserPublicEmailsR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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.+-- See <https://developer.github.com/v3/users/emails/#list-public-email-addresses-for-a-user>+currentUserPublicEmailsR :: FetchCount -> Request 'RA (Vector Email)+currentUserPublicEmailsR =+    pagedQuery ["user", "public_emails"] []
+ src/GitHub/Endpoints/Users/Followers.hs view
@@ -0,0 +1,25 @@+-- |+-- The user followers API as described on+-- <http://developer.github.com/v3/users/followers/>.++module GitHub.Endpoints.Users.Followers (+    usersFollowingR,+    usersFollowedByR,+    module GitHub.Data,+    ) where++import GitHub.Data+import GitHub.Internal.Prelude+import Prelude ()++-- | 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"] []++-- | List users followed by another user.+-- See <https://developer.github.com/v3/users/followers/#list-users-followed-by-another-user>+usersFollowedByR :: Name User -> FetchCount -> Request k (Vector SimpleUser)+usersFollowedByR user =+    pagedQuery ["users", toPathPart user, "following"] []
+ 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
@@ -0,0 +1,30 @@+{-# LANGUAGE NoImplicitPrelude #-}++-- |+-- This module may change between minor releases. Do not rely on its contents.++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         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
@@ -0,0 +1,588 @@+{-# LANGUAGE CPP                    #-}+{-# LANGUAGE FlexibleContexts       #-}+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs                  #-}+{-# LANGUAGE KindSignatures         #-}+{-# LANGUAGE ScopedTypeVariables    #-}+{-# LANGUAGE UndecidableInstances   #-}++-- |+-- This module provides data types and helper methods, which makes possible+-- to build alternative API request intepreters in addition to provided+-- 'IO' functions.+--+-- Simple example using @operational@ package. See @samples\/Operational\/Operational.hs@+--+-- > type GithubMonad a = Program (GH.Request 'False) a+-- >+-- > -- | Intepret GithubMonad value into IO+-- > runMonad :: Manager -> GH.Auth -> GithubMonad a -> ExceptT GH.Error IO a+-- > runMonad mgr auth m = case view m of+-- >    Return a   -> return a+-- >    req :>>= k -> do+-- >        b <- ExceptT $ GH.executeRequestWithMgr mgr auth req+-- >        runMonad mgr auth (k b)+-- >+-- > -- | 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,+    GenRequest (..),+    CommandMethod(..),+    toMethod,+    Paths,+    QueryString,+    -- * Request execution in IO+    executeRequest,+    executeRequestWithMgr,+    executeRequestWithMgrAndRes,+    executeRequest',+    executeRequestWithMgr',+    executeRequestMaybe,+    unsafeDropAuthRequirements,+    -- * Helpers+    Accept (..),+    ParseResponse (..),+    makeHttpRequest,+    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 ()++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                 (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 (..), 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.Types       (Method, RequestHeaders, Status (..))+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 Network.HTTP.Client          as HTTP+import qualified Network.HTTP.Client.Internal as HTTP++#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++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++-- | 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+    :: (AuthMethod am, ParseResponse mt a)+    => Manager+    -> am+    -> GenRequest mt rw a+    -> IO (Either Error a)+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 (HTTP.Response LBS.ByteString)+    httpLbs' req' = lift (httpLbs req' mgr) `catch` onHttpException++    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+        (<$ res) <$> unTagged (parseResponse httpReq res :: Tagged mt (ExceptT Error IO b))++    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' :: ParseResponse mt a => GenRequest mt 'RO a -> IO (Either Error a)+executeRequest' req = withOpenSSL $ do+    manager <- newManager tlsManagerSettings+    executeRequestWithMgr' manager req++-- | Like 'executeRequestWithMgr' but without authentication.+executeRequestWithMgr'+    :: ParseResponse mt a+    => Manager+    -> GenRequest mt 'RO a+    -> IO (Either Error a)+executeRequestWithMgr' mgr = executeRequestWithMgr mgr ()++-- | Helper for picking between 'executeRequest' and 'executeRequest''.+--+-- The use is discouraged.+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 :: 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+------------------------------------------------------------------------------++-- | Create @http-client@ 'Request'.+--+-- * for 'PagedQuery', the initial request is created.+-- * for 'Status', the 'Request' for underlying 'Request' is created,+--   status checking is modifying accordingly.+--+makeHttpRequest+    :: 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+    Query paths qs -> do+        req <- parseUrl' $ url paths+        return+            $ setReqHeaders+            . 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+            . 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+            . unTagged (modifyRequest :: Tagged mt (HTTP.Request -> HTTP.Request))+            . maybe id setAuthRequest auth+            . setBody body+            . setMethod (toMethod m)+            $ req+  where+    parseUrl' :: MonadThrow m => String -> m HTTP.Request+    parseUrl' = HTTP.parseUrlThrow++    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 }++    setMethod :: Method -> HTTP.Request -> HTTP.Request+    setMethod m req = req { method = m }++    reqHeaders :: RequestHeaders+    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 }++    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 :: 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 or Link uri -> Bool+    isRelNext = any (== relNextLinkParam) . linkParams++    relNextLinkParam :: (LinkParam, Text)+    relNextLinkParam = (Rel, "next")++-- | 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' ('HTTP.Response' 'LBS.ByteString'))+--                     -> (a -> 'Bool')+--                     -> 'HTTP.Request'+--                     -> 'ExceptT' 'Error' 'IO' ('HTTP.Response' a)+-- @+performPagedRequest+    :: 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 <- unTagged (parseResponse initReq res :: Tagged mt (m a))+    go m res initReq+  where+    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 <- unTagged (parseResponse req' res' :: Tagged mt (m a))+                go (acc <> m) res' req'+            (_, _)           -> 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)++-- | 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++-------------------------------------------------------------------------------+-- Internal+-------------------------------------------------------------------------------++onHttpException :: MonadError Error m => HttpException -> m a+onHttpException = throwError . HTTPError