Typed, transport-independent GitHub clients for Swift.
This package belongs to the Swift Institute Foundations layer. It turns the contracts from swift-github-standard into injectable async capabilities without choosing HTTP, authentication, persistence, or application policy.
| Product | Module | Purpose |
|---|---|---|
| GitHub | GitHub |
Typed one-call clients and bounded paginated traversals |
| GitHub OAuth | GitHub_OAuth |
Authorization and token exchange |
| GitHub Organizations | GitHub_Organizations |
Organization repository listing and bounded traversal |
| GitHub Repositories | GitHub_Repositories |
Repository lookup and content retrieval |
| GitHub Stargazers | GitHub_Stargazers |
Timestamped stargazer listing and bounded traversal |
| GitHub Traffic | GitHub_Traffic |
Repository views, clones, paths, and referrers |
| GitHub Users | GitHub_Users |
Authenticated-user profile, emails, and repository listing |
dependencies: [
.package(
url: "https://github.com/swift-foundations/swift-github.git",
branch: "main"
)
].target(
name: "YourTarget",
dependencies: [
.product(name: "GitHub", package: "swift-github")
]
)Each resource is also its own product, so a consumer that only needs one
resource can depend on it directly instead of the GitHub umbrella:
.target(
name: "YourTarget",
dependencies: [
.product(name: "GitHub Traffic", package: "swift-github")
]
)The six per-resource products are GitHub OAuth, GitHub Organizations,
GitHub Repositories, GitHub Stargazers, GitHub Traffic, and
GitHub Users — see Products above.
Clients are generic over their typed failure:
import GitHub
let traffic = GitHub.Repository.Traffic.Client<MyError>(
views: fetchViews,
clones: fetchClones,
paths: fetchPaths,
referrers: fetchReferrers
)
let response = try await traffic.views(
.init(
owner: .init(rawValue: "swiftlang"),
repository: .init(rawValue: "swift"),
interval: .day
)
)Repository lookup and authenticated-user repository listing use
GitHub.Repository.Get.Client and GitHub.User.Repositories.Client.
Timestamped stars use GitHub.Repository.Stargazers.Client.
OAuth authorization and token exchange use
GitHub.OAuth.Authorization.Client and GitHub.OAuth.Token.Exchange.Client.
The supporting Users API operations remain
GitHub.User.Authenticated.Get.Client and
GitHub.User.Authenticated.Emails.List.Client.
Paginated repository and stargazer traversal requires explicit page and item limits. Traversal observes task cancellation and fails on client errors, page cycles, or exceeded bounds rather than returning an incomplete result.
This package defines no live or configured-live client. The HTTP binding lives in swift-github-http. Aggregating views, clones, paths, and referrers into an application snapshot is application policy and is intentionally outside this package.
GitHub Traffic, GitHub Stargazers, and GitHub Repositories are
first-class per-resource products (see Products above) that a consumer can
depend on directly. They are not deprecated compatibility shims for the
GitHub umbrella.
One-call clients throw their caller-supplied Failure directly. Bounded
traversal wraps that Failure in a typed error the package owns:
GitHub.Organization.Repositories.Client.all throws
GitHub.Organization.Repositories.Traversal.Error<Failure>, whose cases name
every way a traversal stops short of a complete result:
Traversal.Error<Failure>
├─ cancellation the task was cancelled mid-traversal
├─ client(Failure) the injected page fetch threw your Failure
├─ cycle a request repeated (pagination loop)
├─ duplicate(GitHub.Repository.ID) a repository recurred under `.reject`
├─ items the accumulated item limit was exceeded
└─ pages the page limit was exceeded
Because the throw is typed, the catch is exhaustive with no default:
do {
let repositories = try await client.all(
request,
limit: limit,
duplicate: .reject,
order: .server
)
// use repositories
} catch {
switch error {
case .cancellation:
// traversal observed task cancellation
case .client(let failure):
// the injected page closure failed with your Failure
case .cycle:
// pagination returned to an already-seen request
case .duplicate(let id):
// `.reject` found the same repository twice
case .items:
// accumulated items exceeded limit.items
case .pages:
// fetched pages exceeded limit.pages
}
}The stargazer and authenticated-user repository traversals
(GitHub.Repository.Stargazers.Client.all and
GitHub.User.Repositories.Client.all) throw the same-shaped
Traversal.Error<Failure> without the .duplicate case.
workspace package build
workspace package testThis package is available under the MIT license.