docs(ax): complete v0.8.0 usage examples
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
0513b94d87
commit
a5dc900fd5
28 changed files with 720 additions and 55 deletions
54
actions.go
54
actions.go
|
|
@ -11,7 +11,7 @@ import (
|
|||
// organisations — secrets, variables, and workflow dispatches.
|
||||
// No Resource embedding — heterogeneous endpoints across repo and org levels.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Actions.ListRepoSecrets(ctx, "core", "go-forge")
|
||||
|
|
@ -24,12 +24,20 @@ func newActionsService(c *Client) *ActionsService {
|
|||
}
|
||||
|
||||
// ListRepoSecrets returns all secrets for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListRepoSecrets(ctx, owner, repo)
|
||||
func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string) ([]types.Secret, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/secrets", pathParams("owner", owner, "repo", repo))
|
||||
return ListAll[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoSecrets returns an iterator over all secrets for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterRepoSecrets(ctx, owner, repo)
|
||||
func (s *ActionsService) IterRepoSecrets(ctx context.Context, owner, repo string) iter.Seq2[types.Secret, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/secrets", pathParams("owner", owner, "repo", repo))
|
||||
return ListIter[types.Secret](ctx, s.client, path, nil)
|
||||
|
|
@ -37,6 +45,10 @@ func (s *ActionsService) IterRepoSecrets(ctx context.Context, owner, repo string
|
|||
|
||||
// CreateRepoSecret creates or updates a secret in a repository.
|
||||
// Forgejo expects a PUT with {"data": "secret-value"} body.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.CreateRepoSecret(ctx, owner, repo, name, data)
|
||||
func (s *ActionsService) CreateRepoSecret(ctx context.Context, owner, repo, name string, data string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/secrets/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
body := map[string]string{"data": data}
|
||||
|
|
@ -44,18 +56,30 @@ func (s *ActionsService) CreateRepoSecret(ctx context.Context, owner, repo, name
|
|||
}
|
||||
|
||||
// DeleteRepoSecret removes a secret from a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteRepoSecret(ctx, owner, repo, name)
|
||||
func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/secrets/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListRepoVariables returns all action variables for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListRepoVariables(ctx, owner, repo)
|
||||
func (s *ActionsService) ListRepoVariables(ctx context.Context, owner, repo string) ([]types.ActionVariable, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/variables", pathParams("owner", owner, "repo", repo))
|
||||
return ListAll[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoVariables returns an iterator over all action variables for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterRepoVariables(ctx, owner, repo)
|
||||
func (s *ActionsService) IterRepoVariables(ctx context.Context, owner, repo string) iter.Seq2[types.ActionVariable, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/variables", pathParams("owner", owner, "repo", repo))
|
||||
return ListIter[types.ActionVariable](ctx, s.client, path, nil)
|
||||
|
|
@ -63,6 +87,10 @@ func (s *ActionsService) IterRepoVariables(ctx context.Context, owner, repo stri
|
|||
|
||||
// CreateRepoVariable creates a new action variable in a repository.
|
||||
// Forgejo expects a POST with {"value": "var-value"} body.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.CreateRepoVariable(ctx, owner, repo, name, value)
|
||||
func (s *ActionsService) CreateRepoVariable(ctx context.Context, owner, repo, name, value string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/variables/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
body := types.CreateVariableOption{Value: value}
|
||||
|
|
@ -70,36 +98,60 @@ func (s *ActionsService) CreateRepoVariable(ctx context.Context, owner, repo, na
|
|||
}
|
||||
|
||||
// DeleteRepoVariable removes an action variable from a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteRepoVariable(ctx, owner, repo, name)
|
||||
func (s *ActionsService) DeleteRepoVariable(ctx context.Context, owner, repo, name string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/variables/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgSecrets returns all secrets for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgSecrets(ctx, org)
|
||||
func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string) ([]types.Secret, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/actions/secrets", pathParams("org", org))
|
||||
return ListAll[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgSecrets returns an iterator over all secrets for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgSecrets(ctx, org)
|
||||
func (s *ActionsService) IterOrgSecrets(ctx context.Context, org string) iter.Seq2[types.Secret, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/actions/secrets", pathParams("org", org))
|
||||
return ListIter[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// ListOrgVariables returns all action variables for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgVariables(ctx, org)
|
||||
func (s *ActionsService) ListOrgVariables(ctx context.Context, org string) ([]types.ActionVariable, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/actions/variables", pathParams("org", org))
|
||||
return ListAll[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgVariables returns an iterator over all action variables for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgVariables(ctx, org)
|
||||
func (s *ActionsService) IterOrgVariables(ctx context.Context, org string) iter.Seq2[types.ActionVariable, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/actions/variables", pathParams("org", org))
|
||||
return ListIter[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// DispatchWorkflow triggers a workflow run.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DispatchWorkflow(ctx, owner, repo, workflow, opts)
|
||||
func (s *ActionsService) DispatchWorkflow(ctx context.Context, owner, repo, workflow string, opts map[string]any) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches", pathParams("owner", owner, "repo", repo, "workflow", workflow))
|
||||
return s.client.Post(ctx, path, opts, nil)
|
||||
|
|
|
|||
54
admin.go
54
admin.go
|
|
@ -11,7 +11,7 @@ import (
|
|||
// Unlike other services, AdminService does not embed Resource[T,C,U]
|
||||
// because admin endpoints are heterogeneous.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Admin.ListUsers(ctx)
|
||||
|
|
@ -24,16 +24,28 @@ func newAdminService(c *Client) *AdminService {
|
|||
}
|
||||
|
||||
// ListUsers returns all users (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListUsers(ctx)
|
||||
func (s *AdminService) ListUsers(ctx context.Context) ([]types.User, error) {
|
||||
return ListAll[types.User](ctx, s.client, "/api/v1/admin/users", nil)
|
||||
}
|
||||
|
||||
// IterUsers returns an iterator over all users (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterUsers(ctx)
|
||||
func (s *AdminService) IterUsers(ctx context.Context) iter.Seq2[types.User, error] {
|
||||
return ListIter[types.User](ctx, s.client, "/api/v1/admin/users", nil)
|
||||
}
|
||||
|
||||
// CreateUser creates a new user (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateUser(ctx, opts)
|
||||
func (s *AdminService) CreateUser(ctx context.Context, opts *types.CreateUserOption) (*types.User, error) {
|
||||
var out types.User
|
||||
if err := s.client.Post(ctx, "/api/v1/admin/users", opts, &out); err != nil {
|
||||
|
|
@ -43,56 +55,96 @@ func (s *AdminService) CreateUser(ctx context.Context, opts *types.CreateUserOpt
|
|||
}
|
||||
|
||||
// EditUser edits an existing user (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.EditUser(ctx, username, opts)
|
||||
func (s *AdminService) EditUser(ctx context.Context, username string, opts map[string]any) error {
|
||||
path := ResolvePath("/api/v1/admin/users/{username}", Params{"username": username})
|
||||
return s.client.Patch(ctx, path, opts, nil)
|
||||
}
|
||||
|
||||
// DeleteUser deletes a user (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteUser(ctx, username)
|
||||
func (s *AdminService) DeleteUser(ctx context.Context, username string) error {
|
||||
path := ResolvePath("/api/v1/admin/users/{username}", Params{"username": username})
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// RenameUser renames a user (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RenameUser(ctx, username, newName)
|
||||
func (s *AdminService) RenameUser(ctx context.Context, username, newName string) error {
|
||||
path := ResolvePath("/api/v1/admin/users/{username}/rename", Params{"username": username})
|
||||
return s.client.Post(ctx, path, &types.RenameUserOption{NewName: newName}, nil)
|
||||
}
|
||||
|
||||
// ListOrgs returns all organisations (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgs(ctx)
|
||||
func (s *AdminService) ListOrgs(ctx context.Context) ([]types.Organization, error) {
|
||||
return ListAll[types.Organization](ctx, s.client, "/api/v1/admin/orgs", nil)
|
||||
}
|
||||
|
||||
// IterOrgs returns an iterator over all organisations (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgs(ctx)
|
||||
func (s *AdminService) IterOrgs(ctx context.Context) iter.Seq2[types.Organization, error] {
|
||||
return ListIter[types.Organization](ctx, s.client, "/api/v1/admin/orgs", nil)
|
||||
}
|
||||
|
||||
// RunCron runs a cron task by name (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RunCron(ctx, task)
|
||||
func (s *AdminService) RunCron(ctx context.Context, task string) error {
|
||||
path := ResolvePath("/api/v1/admin/cron/{task}", Params{"task": task})
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// ListCron returns all cron tasks (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListCron(ctx)
|
||||
func (s *AdminService) ListCron(ctx context.Context) ([]types.Cron, error) {
|
||||
return ListAll[types.Cron](ctx, s.client, "/api/v1/admin/cron", nil)
|
||||
}
|
||||
|
||||
// IterCron returns an iterator over all cron tasks (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterCron(ctx)
|
||||
func (s *AdminService) IterCron(ctx context.Context) iter.Seq2[types.Cron, error] {
|
||||
return ListIter[types.Cron](ctx, s.client, "/api/v1/admin/cron", nil)
|
||||
}
|
||||
|
||||
// AdoptRepo adopts an unadopted repository (admin only).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AdoptRepo(ctx, owner, repo)
|
||||
func (s *AdminService) AdoptRepo(ctx context.Context, owner, repo string) error {
|
||||
path := ResolvePath("/api/v1/admin/unadopted/{owner}/{repo}", Params{"owner": owner, "repo": repo})
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// GenerateRunnerToken generates an actions runner registration token.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GenerateRunnerToken(ctx)
|
||||
func (s *AdminService) GenerateRunnerToken(ctx context.Context) (string, error) {
|
||||
var out struct {
|
||||
Token string `json:"token"`
|
||||
|
|
|
|||
26
branches.go
26
branches.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// BranchService handles branch operations within a repository.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Branches.ListBranchProtections(ctx, "core", "go-forge")
|
||||
|
|
@ -26,18 +26,30 @@ func newBranchService(c *Client) *BranchService {
|
|||
}
|
||||
|
||||
// ListBranchProtections returns all branch protections for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListBranchProtections(ctx, owner, repo)
|
||||
func (s *BranchService) ListBranchProtections(ctx context.Context, owner, repo string) ([]types.BranchProtection, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections", pathParams("owner", owner, "repo", repo))
|
||||
return ListAll[types.BranchProtection](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterBranchProtections returns an iterator over all branch protections for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterBranchProtections(ctx, owner, repo)
|
||||
func (s *BranchService) IterBranchProtections(ctx context.Context, owner, repo string) iter.Seq2[types.BranchProtection, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections", pathParams("owner", owner, "repo", repo))
|
||||
return ListIter[types.BranchProtection](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetBranchProtection returns a single branch protection by name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetBranchProtection(ctx, owner, repo, name)
|
||||
func (s *BranchService) GetBranchProtection(ctx context.Context, owner, repo, name string) (*types.BranchProtection, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
var out types.BranchProtection
|
||||
|
|
@ -48,6 +60,10 @@ func (s *BranchService) GetBranchProtection(ctx context.Context, owner, repo, na
|
|||
}
|
||||
|
||||
// CreateBranchProtection creates a new branch protection rule.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateBranchProtection(ctx, owner, repo, opts)
|
||||
func (s *BranchService) CreateBranchProtection(ctx context.Context, owner, repo string, opts *types.CreateBranchProtectionOption) (*types.BranchProtection, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections", pathParams("owner", owner, "repo", repo))
|
||||
var out types.BranchProtection
|
||||
|
|
@ -58,6 +74,10 @@ func (s *BranchService) CreateBranchProtection(ctx context.Context, owner, repo
|
|||
}
|
||||
|
||||
// EditBranchProtection updates an existing branch protection rule.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.EditBranchProtection(ctx, owner, repo, name, opts)
|
||||
func (s *BranchService) EditBranchProtection(ctx context.Context, owner, repo, name string, opts *types.EditBranchProtectionOption) (*types.BranchProtection, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
var out types.BranchProtection
|
||||
|
|
@ -68,6 +88,10 @@ func (s *BranchService) EditBranchProtection(ctx context.Context, owner, repo, n
|
|||
}
|
||||
|
||||
// DeleteBranchProtection deletes a branch protection rule.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteBranchProtection(ctx, owner, repo, name)
|
||||
func (s *BranchService) DeleteBranchProtection(ctx context.Context, owner, repo, name string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/branch_protections/{name}", pathParams("owner", owner, "repo", repo, "name", name))
|
||||
return s.client.Delete(ctx, path)
|
||||
|
|
|
|||
61
client.go
61
client.go
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
// APIError represents an error response from the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// if apiErr, ok := err.(*forge.APIError); ok {
|
||||
// _ = apiErr.StatusCode
|
||||
|
|
@ -24,13 +24,18 @@ type APIError struct {
|
|||
URL string
|
||||
}
|
||||
|
||||
// Error returns the API error as a diagnostic string.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = e.Error()
|
||||
func (e *APIError) Error() string {
|
||||
return core.Concat("forge: ", e.URL, " ", strconv.Itoa(e.StatusCode), ": ", e.Message)
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is a 404 response.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// if forge.IsNotFound(err) {
|
||||
// return nil
|
||||
|
|
@ -42,7 +47,7 @@ func IsNotFound(err error) bool {
|
|||
|
||||
// IsForbidden returns true if the error is a 403 response.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// if forge.IsForbidden(err) {
|
||||
// return nil
|
||||
|
|
@ -54,7 +59,7 @@ func IsForbidden(err error) bool {
|
|||
|
||||
// IsConflict returns true if the error is a 409 response.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// if forge.IsConflict(err) {
|
||||
// return nil
|
||||
|
|
@ -66,14 +71,14 @@ func IsConflict(err error) bool {
|
|||
|
||||
// Option configures the Client.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// opts := []forge.Option{forge.WithUserAgent("go-forge/1.0")}
|
||||
type Option func(*Client)
|
||||
|
||||
// WithHTTPClient sets a custom http.Client.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// c := forge.NewClient(url, token, forge.WithHTTPClient(http.DefaultClient))
|
||||
func WithHTTPClient(hc *http.Client) Option {
|
||||
|
|
@ -82,7 +87,7 @@ func WithHTTPClient(hc *http.Client) Option {
|
|||
|
||||
// WithUserAgent sets the User-Agent header.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// c := forge.NewClient(url, token, forge.WithUserAgent("go-forge/1.0"))
|
||||
func WithUserAgent(ua string) Option {
|
||||
|
|
@ -91,7 +96,7 @@ func WithUserAgent(ua string) Option {
|
|||
|
||||
// RateLimit represents the rate limit information from the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// rl := client.RateLimit()
|
||||
// _ = rl.Remaining
|
||||
|
|
@ -103,7 +108,7 @@ type RateLimit struct {
|
|||
|
||||
// Client is a low-level HTTP client for the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// c := forge.NewClient("https://forge.lthn.ai", "token")
|
||||
// _ = c
|
||||
|
|
@ -116,13 +121,17 @@ type Client struct {
|
|||
}
|
||||
|
||||
// RateLimit returns the last known rate limit information.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = c.RateLimit()
|
||||
func (c *Client) RateLimit() RateLimit {
|
||||
return c.rateLimit
|
||||
}
|
||||
|
||||
// NewClient creates a new Forgejo API client.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// c := forge.NewClient("https://forge.lthn.ai", "token")
|
||||
// _ = c
|
||||
|
|
@ -144,36 +153,60 @@ func NewClient(url, token string, opts ...Option) *Client {
|
|||
}
|
||||
|
||||
// Get performs a GET request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.Get(ctx, path, out)
|
||||
func (c *Client) Get(ctx context.Context, path string, out any) error {
|
||||
_, err := c.doJSON(ctx, http.MethodGet, path, nil, out)
|
||||
return err
|
||||
}
|
||||
|
||||
// Post performs a POST request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.Post(ctx, path, body, out)
|
||||
func (c *Client) Post(ctx context.Context, path string, body, out any) error {
|
||||
_, err := c.doJSON(ctx, http.MethodPost, path, body, out)
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch performs a PATCH request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.Patch(ctx, path, body, out)
|
||||
func (c *Client) Patch(ctx context.Context, path string, body, out any) error {
|
||||
_, err := c.doJSON(ctx, http.MethodPatch, path, body, out)
|
||||
return err
|
||||
}
|
||||
|
||||
// Put performs a PUT request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.Put(ctx, path, body, out)
|
||||
func (c *Client) Put(ctx context.Context, path string, body, out any) error {
|
||||
_, err := c.doJSON(ctx, http.MethodPut, path, body, out)
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete performs a DELETE request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.Delete(ctx, path)
|
||||
func (c *Client) Delete(ctx context.Context, path string) error {
|
||||
_, err := c.doJSON(ctx, http.MethodDelete, path, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteWithBody performs a DELETE request with a JSON body.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := c.DeleteWithBody(ctx, path, body)
|
||||
func (c *Client) DeleteWithBody(ctx context.Context, path string, body any) error {
|
||||
_, err := c.doJSON(ctx, http.MethodDelete, path, body, nil)
|
||||
return err
|
||||
|
|
@ -182,6 +215,10 @@ func (c *Client) DeleteWithBody(ctx context.Context, path string, body any) erro
|
|||
// PostRaw performs a POST request with a JSON body and returns the raw
|
||||
// response body as bytes instead of JSON-decoding. Useful for endpoints
|
||||
// such as /markdown that return raw HTML text.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := c.PostRaw(ctx, path, body)
|
||||
func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, error) {
|
||||
url := c.baseURL + path
|
||||
|
||||
|
|
@ -225,6 +262,10 @@ func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, er
|
|||
|
||||
// GetRaw performs a GET request and returns the raw response body as bytes
|
||||
// instead of JSON-decoding. Useful for endpoints that return raw file content.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := c.GetRaw(ctx, path)
|
||||
func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error) {
|
||||
url := c.baseURL + path
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ type templateData struct {
|
|||
|
||||
// Generate writes Go source files for the extracted types, grouped by logical domain.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// err := Generate(types, pairs, "types")
|
||||
// _ = err
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
// Spec represents a Swagger 2.0 specification document.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// spec, err := LoadSpec("testdata/swagger.v1.json")
|
||||
// _ = spec
|
||||
|
|
@ -24,7 +24,7 @@ type Spec struct {
|
|||
|
||||
// SpecInfo holds metadata about the API specification.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = SpecInfo{Title: "Forgejo API", Version: "1.0"}
|
||||
type SpecInfo struct {
|
||||
|
|
@ -34,7 +34,7 @@ type SpecInfo struct {
|
|||
|
||||
// SchemaDefinition represents a single type definition in the swagger spec.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = SchemaDefinition{Type: "object"}
|
||||
type SchemaDefinition struct {
|
||||
|
|
@ -48,7 +48,7 @@ type SchemaDefinition struct {
|
|||
|
||||
// SchemaProperty represents a single property within a schema definition.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = SchemaProperty{Type: "string"}
|
||||
type SchemaProperty struct {
|
||||
|
|
@ -63,7 +63,7 @@ type SchemaProperty struct {
|
|||
|
||||
// GoType is the intermediate representation for a Go type to be generated.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = GoType{Name: "Repository"}
|
||||
type GoType struct {
|
||||
|
|
@ -76,7 +76,7 @@ type GoType struct {
|
|||
|
||||
// GoField is the intermediate representation for a single struct field.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = GoField{GoName: "ID", GoType: "int64"}
|
||||
type GoField struct {
|
||||
|
|
@ -89,7 +89,7 @@ type GoField struct {
|
|||
|
||||
// CRUDPair groups a base type with its corresponding Create and Edit option types.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// _ = CRUDPair{Base: "Repository", Create: "CreateRepoOption", Edit: "EditRepoOption"}
|
||||
type CRUDPair struct {
|
||||
|
|
@ -100,7 +100,7 @@ type CRUDPair struct {
|
|||
|
||||
// LoadSpec reads and parses a Swagger 2.0 JSON file from the given path.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// spec, err := LoadSpec("testdata/swagger.v1.json")
|
||||
// _ = spec
|
||||
|
|
@ -118,7 +118,7 @@ func LoadSpec(path string) (*Spec, error) {
|
|||
|
||||
// ExtractTypes converts all swagger definitions into Go type intermediate representations.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// types := ExtractTypes(spec)
|
||||
// _ = types["Repository"]
|
||||
|
|
@ -164,7 +164,7 @@ func ExtractTypes(spec *Spec) map[string]*GoType {
|
|||
// DetectCRUDPairs finds Create*Option / Edit*Option pairs in the swagger definitions
|
||||
// and maps them back to the base type name.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// pairs := DetectCRUDPairs(spec)
|
||||
// _ = pairs
|
||||
|
|
|
|||
34
commits.go
34
commits.go
|
|
@ -12,7 +12,7 @@ import (
|
|||
// No Resource embedding — collection and item commit paths differ, and the
|
||||
// remaining endpoints are heterogeneous across status and note paths.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Commits.GetCombinedStatus(ctx, "core", "go-forge", "main")
|
||||
|
|
@ -30,21 +30,37 @@ func newCommitService(c *Client) *CommitService {
|
|||
}
|
||||
|
||||
// List returns a single page of commits for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.List(ctx, params, opts)
|
||||
func (s *CommitService) List(ctx context.Context, params Params, opts ListOptions) (*PagedResult[types.Commit], error) {
|
||||
return ListPage[types.Commit](ctx, s.client, ResolvePath(commitCollectionPath, params), nil, opts)
|
||||
}
|
||||
|
||||
// ListAll returns all commits for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListAll(ctx, params)
|
||||
func (s *CommitService) ListAll(ctx context.Context, params Params) ([]types.Commit, error) {
|
||||
return ListAll[types.Commit](ctx, s.client, ResolvePath(commitCollectionPath, params), nil)
|
||||
}
|
||||
|
||||
// Iter returns an iterator over all commits for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.Iter(ctx, params)
|
||||
func (s *CommitService) Iter(ctx context.Context, params Params) iter.Seq2[types.Commit, error] {
|
||||
return ListIter[types.Commit](ctx, s.client, ResolvePath(commitCollectionPath, params), nil)
|
||||
}
|
||||
|
||||
// Get returns a single commit by SHA or ref.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.Get(ctx, params)
|
||||
func (s *CommitService) Get(ctx context.Context, params Params) (*types.Commit, error) {
|
||||
var out types.Commit
|
||||
if err := s.client.Get(ctx, ResolvePath(commitItemPath, params), &out); err != nil {
|
||||
|
|
@ -54,6 +70,10 @@ func (s *CommitService) Get(ctx context.Context, params Params) (*types.Commit,
|
|||
}
|
||||
|
||||
// GetCombinedStatus returns the combined status for a given ref (branch, tag, or SHA).
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetCombinedStatus(ctx, owner, repo, ref)
|
||||
func (s *CommitService) GetCombinedStatus(ctx context.Context, owner, repo, ref string) (*types.CombinedStatus, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/statuses/{ref}", pathParams("owner", owner, "repo", repo, "ref", ref))
|
||||
var out types.CombinedStatus
|
||||
|
|
@ -64,6 +84,10 @@ func (s *CommitService) GetCombinedStatus(ctx context.Context, owner, repo, ref
|
|||
}
|
||||
|
||||
// ListStatuses returns all commit statuses for a given ref.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListStatuses(ctx, owner, repo, ref)
|
||||
func (s *CommitService) ListStatuses(ctx context.Context, owner, repo, ref string) ([]types.CommitStatus, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/commits/{ref}/statuses", pathParams("owner", owner, "repo", repo, "ref", ref))
|
||||
var out []types.CommitStatus
|
||||
|
|
@ -74,6 +98,10 @@ func (s *CommitService) ListStatuses(ctx context.Context, owner, repo, ref strin
|
|||
}
|
||||
|
||||
// CreateStatus creates a new commit status for the given SHA.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateStatus(ctx, owner, repo, sha, opts)
|
||||
func (s *CommitService) CreateStatus(ctx context.Context, owner, repo, sha string, opts *types.CreateStatusOption) (*types.CommitStatus, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/statuses/{sha}", pathParams("owner", owner, "repo", repo, "sha", sha))
|
||||
var out types.CommitStatus
|
||||
|
|
@ -84,6 +112,10 @@ func (s *CommitService) CreateStatus(ctx context.Context, owner, repo, sha strin
|
|||
}
|
||||
|
||||
// GetNote returns the git note for a given commit SHA.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetNote(ctx, owner, repo, sha)
|
||||
func (s *CommitService) GetNote(ctx context.Context, owner, repo, sha string) (*types.Note, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/git/notes/{sha}", pathParams("owner", owner, "repo", repo, "sha", sha))
|
||||
var out types.Note
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const (
|
|||
// - FORGE_URL — base URL of the Forgejo instance
|
||||
// - FORGE_TOKEN — API token for authentication
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// url, token, err := forge.ResolveConfig("", "")
|
||||
// _ = url
|
||||
|
|
@ -47,7 +47,7 @@ func ResolveConfig(flagURL, flagToken string) (url, token string, err error) {
|
|||
// NewForgeFromConfig creates a new Forge client using resolved configuration.
|
||||
// It returns an error if no API token is available from flags or environment.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f, err := forge.NewForgeFromConfig("", "")
|
||||
// _ = f
|
||||
|
|
|
|||
22
contents.go
22
contents.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
// ContentService handles file read/write operations via the Forgejo API.
|
||||
// No Resource embedding — paths vary by operation.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Contents.GetFile(ctx, "core", "go-forge", "README.md")
|
||||
|
|
@ -22,6 +22,10 @@ func newContentService(c *Client) *ContentService {
|
|||
}
|
||||
|
||||
// GetFile returns metadata and content for a file in a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetFile(ctx, owner, repo, filepath)
|
||||
func (s *ContentService) GetFile(ctx context.Context, owner, repo, filepath string) (*types.ContentsResponse, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/contents/{filepath}", pathParams("owner", owner, "repo", repo, "filepath", filepath))
|
||||
var out types.ContentsResponse
|
||||
|
|
@ -32,6 +36,10 @@ func (s *ContentService) GetFile(ctx context.Context, owner, repo, filepath stri
|
|||
}
|
||||
|
||||
// CreateFile creates a new file in a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateFile(ctx, owner, repo, filepath, opts)
|
||||
func (s *ContentService) CreateFile(ctx context.Context, owner, repo, filepath string, opts *types.CreateFileOptions) (*types.FileResponse, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/contents/{filepath}", pathParams("owner", owner, "repo", repo, "filepath", filepath))
|
||||
var out types.FileResponse
|
||||
|
|
@ -42,6 +50,10 @@ func (s *ContentService) CreateFile(ctx context.Context, owner, repo, filepath s
|
|||
}
|
||||
|
||||
// UpdateFile updates an existing file in a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.UpdateFile(ctx, owner, repo, filepath, opts)
|
||||
func (s *ContentService) UpdateFile(ctx context.Context, owner, repo, filepath string, opts *types.UpdateFileOptions) (*types.FileResponse, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/contents/{filepath}", pathParams("owner", owner, "repo", repo, "filepath", filepath))
|
||||
var out types.FileResponse
|
||||
|
|
@ -52,12 +64,20 @@ func (s *ContentService) UpdateFile(ctx context.Context, owner, repo, filepath s
|
|||
}
|
||||
|
||||
// DeleteFile deletes a file from a repository. Uses DELETE with a JSON body.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteFile(ctx, owner, repo, filepath, opts)
|
||||
func (s *ContentService) DeleteFile(ctx context.Context, owner, repo, filepath string, opts *types.DeleteFileOptions) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/contents/{filepath}", pathParams("owner", owner, "repo", repo, "filepath", filepath))
|
||||
return s.client.DeleteWithBody(ctx, path, opts)
|
||||
}
|
||||
|
||||
// GetRawFile returns the raw file content as bytes.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetRawFile(ctx, owner, repo, filepath)
|
||||
func (s *ContentService) GetRawFile(ctx context.Context, owner, repo, filepath string) ([]byte, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/raw/{filepath}", pathParams("owner", owner, "repo", repo, "filepath", filepath))
|
||||
return s.client.GetRaw(ctx, path)
|
||||
|
|
|
|||
2
doc.go
2
doc.go
|
|
@ -1,6 +1,6 @@
|
|||
// Package forge provides a full-coverage Go client for the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// ctx := context.Background()
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "your-token")
|
||||
|
|
|
|||
8
forge.go
8
forge.go
|
|
@ -2,7 +2,7 @@ package forge
|
|||
|
||||
// Forge is the top-level client for the Forgejo API.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _ = f.Repos
|
||||
|
|
@ -32,7 +32,7 @@ type Forge struct {
|
|||
|
||||
// NewForge creates a new Forge client.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _ = f
|
||||
|
|
@ -62,4 +62,8 @@ func NewForge(url, token string, opts ...Option) *Forge {
|
|||
}
|
||||
|
||||
// Client returns the underlying HTTP client.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = f.Client()
|
||||
func (f *Forge) Client() *Client { return f.client }
|
||||
|
|
|
|||
50
issues.go
50
issues.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// IssueService handles issue operations within a repository.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Issues.ListAll(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
|
|
@ -26,18 +26,30 @@ func newIssueService(c *Client) *IssueService {
|
|||
}
|
||||
|
||||
// Pin pins an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Pin(ctx, owner, repo, index)
|
||||
func (s *IssueService) Pin(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/pin", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unpin unpins an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Unpin(ctx, owner, repo, index)
|
||||
func (s *IssueService) Unpin(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/pin", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// SetDeadline sets or updates the deadline on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.SetDeadline(ctx, owner, repo, index, deadline)
|
||||
func (s *IssueService) SetDeadline(ctx context.Context, owner, repo string, index int64, deadline string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/deadline", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
body := map[string]string{"due_date": deadline}
|
||||
|
|
@ -45,6 +57,10 @@ func (s *IssueService) SetDeadline(ctx context.Context, owner, repo string, inde
|
|||
}
|
||||
|
||||
// AddReaction adds a reaction to an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AddReaction(ctx, owner, repo, index, reaction)
|
||||
func (s *IssueService) AddReaction(ctx context.Context, owner, repo string, index int64, reaction string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/reactions", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
body := map[string]string{"content": reaction}
|
||||
|
|
@ -52,6 +68,10 @@ func (s *IssueService) AddReaction(ctx context.Context, owner, repo string, inde
|
|||
}
|
||||
|
||||
// DeleteReaction removes a reaction from an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteReaction(ctx, owner, repo, index, reaction)
|
||||
func (s *IssueService) DeleteReaction(ctx context.Context, owner, repo string, index int64, reaction string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/reactions", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
body := map[string]string{"content": reaction}
|
||||
|
|
@ -59,18 +79,30 @@ func (s *IssueService) DeleteReaction(ctx context.Context, owner, repo string, i
|
|||
}
|
||||
|
||||
// StartStopwatch starts the stopwatch on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.StartStopwatch(ctx, owner, repo, index)
|
||||
func (s *IssueService) StartStopwatch(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/stopwatch/start", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// StopStopwatch stops the stopwatch on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.StopStopwatch(ctx, owner, repo, index)
|
||||
func (s *IssueService) StopStopwatch(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/stopwatch/stop", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// AddLabels adds labels to an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AddLabels(ctx, owner, repo, index, labelIDs)
|
||||
func (s *IssueService) AddLabels(ctx context.Context, owner, repo string, index int64, labelIDs []int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/labels", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
body := types.IssueLabelsOption{Labels: toAnySlice(labelIDs)}
|
||||
|
|
@ -78,24 +110,40 @@ func (s *IssueService) AddLabels(ctx context.Context, owner, repo string, index
|
|||
}
|
||||
|
||||
// RemoveLabel removes a single label from an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RemoveLabel(ctx, owner, repo, index, labelID)
|
||||
func (s *IssueService) RemoveLabel(ctx context.Context, owner, repo string, index int64, labelID int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/labels/{labelID}", pathParams("owner", owner, "repo", repo, "index", int64String(index), "labelID", int64String(labelID)))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListComments returns all comments on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListComments(ctx, owner, repo, index)
|
||||
func (s *IssueService) ListComments(ctx context.Context, owner, repo string, index int64) ([]types.Comment, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/comments", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return ListAll[types.Comment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterComments returns an iterator over all comments on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterComments(ctx, owner, repo, index)
|
||||
func (s *IssueService) IterComments(ctx context.Context, owner, repo string, index int64) iter.Seq2[types.Comment, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/comments", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return ListIter[types.Comment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateComment creates a comment on an issue.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateComment(ctx, owner, repo, index, body)
|
||||
func (s *IssueService) CreateComment(ctx context.Context, owner, repo string, index int64, body string) (*types.Comment, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/issues/{index}/comments", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
opts := types.CreateIssueCommentOption{Body: body}
|
||||
|
|
|
|||
38
labels.go
38
labels.go
|
|
@ -10,7 +10,7 @@ import (
|
|||
// LabelService handles repository labels, organisation labels, and issue labels.
|
||||
// No Resource embedding — paths are heterogeneous.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Labels.ListRepoLabels(ctx, "core", "go-forge")
|
||||
|
|
@ -23,18 +23,30 @@ func newLabelService(c *Client) *LabelService {
|
|||
}
|
||||
|
||||
// ListRepoLabels returns all labels for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListRepoLabels(ctx, owner, repo)
|
||||
func (s *LabelService) ListRepoLabels(ctx context.Context, owner, repo string) ([]types.Label, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels", pathParams("owner", owner, "repo", repo))
|
||||
return ListAll[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoLabels returns an iterator over all labels for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterRepoLabels(ctx, owner, repo)
|
||||
func (s *LabelService) IterRepoLabels(ctx context.Context, owner, repo string) iter.Seq2[types.Label, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels", pathParams("owner", owner, "repo", repo))
|
||||
return ListIter[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetRepoLabel returns a single label by ID.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetRepoLabel(ctx, owner, repo, id)
|
||||
func (s *LabelService) GetRepoLabel(ctx context.Context, owner, repo string, id int64) (*types.Label, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels/{id}", pathParams("owner", owner, "repo", repo, "id", int64String(id)))
|
||||
var out types.Label
|
||||
|
|
@ -45,6 +57,10 @@ func (s *LabelService) GetRepoLabel(ctx context.Context, owner, repo string, id
|
|||
}
|
||||
|
||||
// CreateRepoLabel creates a new label in a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateRepoLabel(ctx, owner, repo, opts)
|
||||
func (s *LabelService) CreateRepoLabel(ctx context.Context, owner, repo string, opts *types.CreateLabelOption) (*types.Label, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels", pathParams("owner", owner, "repo", repo))
|
||||
var out types.Label
|
||||
|
|
@ -55,6 +71,10 @@ func (s *LabelService) CreateRepoLabel(ctx context.Context, owner, repo string,
|
|||
}
|
||||
|
||||
// EditRepoLabel updates an existing label in a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.EditRepoLabel(ctx, owner, repo, id, opts)
|
||||
func (s *LabelService) EditRepoLabel(ctx context.Context, owner, repo string, id int64, opts *types.EditLabelOption) (*types.Label, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels/{id}", pathParams("owner", owner, "repo", repo, "id", int64String(id)))
|
||||
var out types.Label
|
||||
|
|
@ -65,24 +85,40 @@ func (s *LabelService) EditRepoLabel(ctx context.Context, owner, repo string, id
|
|||
}
|
||||
|
||||
// DeleteRepoLabel deletes a label from a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteRepoLabel(ctx, owner, repo, id)
|
||||
func (s *LabelService) DeleteRepoLabel(ctx context.Context, owner, repo string, id int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/labels/{id}", pathParams("owner", owner, "repo", repo, "id", int64String(id)))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgLabels returns all labels for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgLabels(ctx, org)
|
||||
func (s *LabelService) ListOrgLabels(ctx context.Context, org string) ([]types.Label, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/labels", pathParams("org", org))
|
||||
return ListAll[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgLabels returns an iterator over all labels for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgLabels(ctx, org)
|
||||
func (s *LabelService) IterOrgLabels(ctx context.Context, org string) iter.Seq2[types.Label, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/labels", pathParams("org", org))
|
||||
return ListIter[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateOrgLabel creates a new label in an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreateOrgLabel(ctx, org, opts)
|
||||
func (s *LabelService) CreateOrgLabel(ctx context.Context, org string, opts *types.CreateLabelOption) (*types.Label, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/labels", pathParams("org", org))
|
||||
var out types.Label
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// MilestoneService handles repository milestones.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Milestones.ListAll(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
|
|
@ -21,12 +21,20 @@ func newMilestoneService(c *Client) *MilestoneService {
|
|||
}
|
||||
|
||||
// ListAll returns all milestones for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListAll(ctx, params)
|
||||
func (s *MilestoneService) ListAll(ctx context.Context, params Params) ([]types.Milestone, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/milestones", params)
|
||||
return ListAll[types.Milestone](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Get returns a single milestone by ID.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.Get(ctx, owner, repo, id)
|
||||
func (s *MilestoneService) Get(ctx context.Context, owner, repo string, id int64) (*types.Milestone, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/milestones/{id}", pathParams("owner", owner, "repo", repo, "id", int64String(id)))
|
||||
var out types.Milestone
|
||||
|
|
@ -37,6 +45,10 @@ func (s *MilestoneService) Get(ctx context.Context, owner, repo string, id int64
|
|||
}
|
||||
|
||||
// Create creates a new milestone.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.Create(ctx, owner, repo, opts)
|
||||
func (s *MilestoneService) Create(ctx context.Context, owner, repo string, opts *types.CreateMilestoneOption) (*types.Milestone, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/milestones", pathParams("owner", owner, "repo", repo))
|
||||
var out types.Milestone
|
||||
|
|
|
|||
30
misc.go
30
misc.go
|
|
@ -11,7 +11,7 @@ import (
|
|||
// server metadata.
|
||||
// No Resource embedding — heterogeneous read-only endpoints.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Misc.GetVersion(ctx)
|
||||
|
|
@ -25,6 +25,10 @@ func newMiscService(c *Client) *MiscService {
|
|||
|
||||
// RenderMarkdown renders markdown text to HTML. The response is raw HTML
|
||||
// text, not JSON.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.RenderMarkdown(ctx, text, mode)
|
||||
func (s *MiscService) RenderMarkdown(ctx context.Context, text, mode string) (string, error) {
|
||||
body := types.MarkdownOption{Text: text, Mode: mode}
|
||||
data, err := s.client.PostRaw(ctx, "/api/v1/markdown", body)
|
||||
|
|
@ -35,6 +39,10 @@ func (s *MiscService) RenderMarkdown(ctx context.Context, text, mode string) (st
|
|||
}
|
||||
|
||||
// ListLicenses returns all available licence templates.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListLicenses(ctx)
|
||||
func (s *MiscService) ListLicenses(ctx context.Context) ([]types.LicensesTemplateListEntry, error) {
|
||||
var out []types.LicensesTemplateListEntry
|
||||
if err := s.client.Get(ctx, "/api/v1/licenses", &out); err != nil {
|
||||
|
|
@ -44,6 +52,10 @@ func (s *MiscService) ListLicenses(ctx context.Context) ([]types.LicensesTemplat
|
|||
}
|
||||
|
||||
// GetLicense returns a single licence template by name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetLicense(ctx, name)
|
||||
func (s *MiscService) GetLicense(ctx context.Context, name string) (*types.LicenseTemplateInfo, error) {
|
||||
path := ResolvePath("/api/v1/licenses/{name}", pathParams("name", name))
|
||||
var out types.LicenseTemplateInfo
|
||||
|
|
@ -54,6 +66,10 @@ func (s *MiscService) GetLicense(ctx context.Context, name string) (*types.Licen
|
|||
}
|
||||
|
||||
// ListGitignoreTemplates returns all available gitignore template names.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListGitignoreTemplates(ctx)
|
||||
func (s *MiscService) ListGitignoreTemplates(ctx context.Context) ([]string, error) {
|
||||
var out []string
|
||||
if err := s.client.Get(ctx, "/api/v1/gitignore/templates", &out); err != nil {
|
||||
|
|
@ -63,6 +79,10 @@ func (s *MiscService) ListGitignoreTemplates(ctx context.Context) ([]string, err
|
|||
}
|
||||
|
||||
// GetGitignoreTemplate returns a single gitignore template by name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetGitignoreTemplate(ctx, name)
|
||||
func (s *MiscService) GetGitignoreTemplate(ctx context.Context, name string) (*types.GitignoreTemplateInfo, error) {
|
||||
path := ResolvePath("/api/v1/gitignore/templates/{name}", pathParams("name", name))
|
||||
var out types.GitignoreTemplateInfo
|
||||
|
|
@ -73,6 +93,10 @@ func (s *MiscService) GetGitignoreTemplate(ctx context.Context, name string) (*t
|
|||
}
|
||||
|
||||
// GetNodeInfo returns the NodeInfo metadata for the Forgejo instance.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetNodeInfo(ctx)
|
||||
func (s *MiscService) GetNodeInfo(ctx context.Context) (*types.NodeInfo, error) {
|
||||
var out types.NodeInfo
|
||||
if err := s.client.Get(ctx, "/api/v1/nodeinfo", &out); err != nil {
|
||||
|
|
@ -82,6 +106,10 @@ func (s *MiscService) GetNodeInfo(ctx context.Context) (*types.NodeInfo, error)
|
|||
}
|
||||
|
||||
// GetVersion returns the server version.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetVersion(ctx)
|
||||
func (s *MiscService) GetVersion(ctx context.Context) (*types.ServerVersion, error) {
|
||||
var out types.ServerVersion
|
||||
if err := s.client.Get(ctx, "/api/v1/version", &out); err != nil {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
// NotificationService handles notification operations via the Forgejo API.
|
||||
// No Resource embedding — varied endpoint shapes.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Notifications.List(ctx)
|
||||
|
|
@ -23,33 +23,57 @@ func newNotificationService(c *Client) *NotificationService {
|
|||
}
|
||||
|
||||
// List returns all notifications for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.List(ctx)
|
||||
func (s *NotificationService) List(ctx context.Context) ([]types.NotificationThread, error) {
|
||||
return ListAll[types.NotificationThread](ctx, s.client, "/api/v1/notifications", nil)
|
||||
}
|
||||
|
||||
// Iter returns an iterator over all notifications for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.Iter(ctx)
|
||||
func (s *NotificationService) Iter(ctx context.Context) iter.Seq2[types.NotificationThread, error] {
|
||||
return ListIter[types.NotificationThread](ctx, s.client, "/api/v1/notifications", nil)
|
||||
}
|
||||
|
||||
// ListRepo returns all notifications for a specific repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListRepo(ctx, owner, repo)
|
||||
func (s *NotificationService) ListRepo(ctx context.Context, owner, repo string) ([]types.NotificationThread, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/notifications", pathParams("owner", owner, "repo", repo))
|
||||
return ListAll[types.NotificationThread](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepo returns an iterator over all notifications for a specific repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterRepo(ctx, owner, repo)
|
||||
func (s *NotificationService) IterRepo(ctx context.Context, owner, repo string) iter.Seq2[types.NotificationThread, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/notifications", pathParams("owner", owner, "repo", repo))
|
||||
return ListIter[types.NotificationThread](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// MarkRead marks all notifications as read.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.MarkRead(ctx)
|
||||
func (s *NotificationService) MarkRead(ctx context.Context) error {
|
||||
return s.client.Put(ctx, "/api/v1/notifications", nil, nil)
|
||||
}
|
||||
|
||||
// GetThread returns a single notification thread by ID.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetThread(ctx, id)
|
||||
func (s *NotificationService) GetThread(ctx context.Context, id int64) (*types.NotificationThread, error) {
|
||||
path := ResolvePath("/api/v1/notifications/threads/{id}", pathParams("id", int64String(id)))
|
||||
var out types.NotificationThread
|
||||
|
|
@ -60,6 +84,10 @@ func (s *NotificationService) GetThread(ctx context.Context, id int64) (*types.N
|
|||
}
|
||||
|
||||
// MarkThreadRead marks a single notification thread as read.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.MarkThreadRead(ctx, id)
|
||||
func (s *NotificationService) MarkThreadRead(ctx context.Context, id int64) error {
|
||||
path := ResolvePath("/api/v1/notifications/threads/{id}", pathParams("id", int64String(id)))
|
||||
return s.client.Patch(ctx, path, nil, nil)
|
||||
|
|
|
|||
34
orgs.go
34
orgs.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// OrgService handles organisation operations.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Orgs.ListMembers(ctx, "core")
|
||||
|
|
@ -26,47 +26,79 @@ func newOrgService(c *Client) *OrgService {
|
|||
}
|
||||
|
||||
// ListMembers returns all members of an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListMembers(ctx, org)
|
||||
func (s *OrgService) ListMembers(ctx context.Context, org string) ([]types.User, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/members", pathParams("org", org))
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterMembers returns an iterator over all members of an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterMembers(ctx, org)
|
||||
func (s *OrgService) IterMembers(ctx context.Context, org string) iter.Seq2[types.User, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/members", pathParams("org", org))
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddMember adds a user to an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AddMember(ctx, org, username)
|
||||
func (s *OrgService) AddMember(ctx context.Context, org, username string) error {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/members/{username}", pathParams("org", org, "username", username))
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveMember removes a user from an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RemoveMember(ctx, org, username)
|
||||
func (s *OrgService) RemoveMember(ctx context.Context, org, username string) error {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/members/{username}", pathParams("org", org, "username", username))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListUserOrgs returns all organisations for a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListUserOrgs(ctx, username)
|
||||
func (s *OrgService) ListUserOrgs(ctx context.Context, username string) ([]types.Organization, error) {
|
||||
path := ResolvePath("/api/v1/users/{username}/orgs", pathParams("username", username))
|
||||
return ListAll[types.Organization](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterUserOrgs returns an iterator over all organisations for a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterUserOrgs(ctx, username)
|
||||
func (s *OrgService) IterUserOrgs(ctx context.Context, username string) iter.Seq2[types.Organization, error] {
|
||||
path := ResolvePath("/api/v1/users/{username}/orgs", pathParams("username", username))
|
||||
return ListIter[types.Organization](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// ListMyOrgs returns all organisations for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListMyOrgs(ctx)
|
||||
func (s *OrgService) ListMyOrgs(ctx context.Context) ([]types.Organization, error) {
|
||||
return ListAll[types.Organization](ctx, s.client, "/api/v1/user/orgs", nil)
|
||||
}
|
||||
|
||||
// IterMyOrgs returns an iterator over all organisations for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterMyOrgs(ctx)
|
||||
func (s *OrgService) IterMyOrgs(ctx context.Context) iter.Seq2[types.Organization, error] {
|
||||
return ListIter[types.Organization](ctx, s.client, "/api/v1/user/orgs", nil)
|
||||
}
|
||||
|
|
|
|||
26
packages.go
26
packages.go
|
|
@ -10,7 +10,7 @@ import (
|
|||
// PackageService handles package registry operations via the Forgejo API.
|
||||
// No Resource embedding — paths vary by operation.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Packages.List(ctx, "core")
|
||||
|
|
@ -23,18 +23,30 @@ func newPackageService(c *Client) *PackageService {
|
|||
}
|
||||
|
||||
// List returns all packages for a given owner.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.List(ctx, owner)
|
||||
func (s *PackageService) List(ctx context.Context, owner string) ([]types.Package, error) {
|
||||
path := ResolvePath("/api/v1/packages/{owner}", pathParams("owner", owner))
|
||||
return ListAll[types.Package](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Iter returns an iterator over all packages for a given owner.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.Iter(ctx, owner)
|
||||
func (s *PackageService) Iter(ctx context.Context, owner string) iter.Seq2[types.Package, error] {
|
||||
path := ResolvePath("/api/v1/packages/{owner}", pathParams("owner", owner))
|
||||
return ListIter[types.Package](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Get returns a single package by owner, type, name, and version.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.Get(ctx, owner, pkgType, name, version)
|
||||
func (s *PackageService) Get(ctx context.Context, owner, pkgType, name, version string) (*types.Package, error) {
|
||||
path := ResolvePath("/api/v1/packages/{owner}/{pkgType}/{name}/{version}", pathParams("owner", owner, "pkgType", pkgType, "name", name, "version", version))
|
||||
var out types.Package
|
||||
|
|
@ -45,18 +57,30 @@ func (s *PackageService) Get(ctx context.Context, owner, pkgType, name, version
|
|||
}
|
||||
|
||||
// Delete removes a package by owner, type, name, and version.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Delete(ctx, owner, pkgType, name, version)
|
||||
func (s *PackageService) Delete(ctx context.Context, owner, pkgType, name, version string) error {
|
||||
path := ResolvePath("/api/v1/packages/{owner}/{pkgType}/{name}/{version}", pathParams("owner", owner, "pkgType", pkgType, "name", name, "version", version))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListFiles returns all files for a specific package version.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListFiles(ctx, owner, pkgType, name, version)
|
||||
func (s *PackageService) ListFiles(ctx context.Context, owner, pkgType, name, version string) ([]types.PackageFile, error) {
|
||||
path := ResolvePath("/api/v1/packages/{owner}/{pkgType}/{name}/{version}/files", pathParams("owner", owner, "pkgType", pkgType, "name", name, "version", version))
|
||||
return ListAll[types.PackageFile](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFiles returns an iterator over all files for a specific package version.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterFiles(ctx, owner, pkgType, name, version)
|
||||
func (s *PackageService) IterFiles(ctx context.Context, owner, pkgType, name, version string) iter.Seq2[types.PackageFile, error] {
|
||||
path := ResolvePath("/api/v1/packages/{owner}/{pkgType}/{name}/{version}/files", pathParams("owner", owner, "pkgType", pkgType, "name", name, "version", version))
|
||||
return ListIter[types.PackageFile](ctx, s.client, path, nil)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
// ListOptions controls pagination.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// opts := forge.ListOptions{Page: 1, Limit: 50}
|
||||
// _ = opts
|
||||
|
|
@ -23,7 +23,7 @@ type ListOptions struct {
|
|||
|
||||
// DefaultList returns sensible default pagination.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// page, err := forge.ListPage[types.Repository](ctx, client, path, nil, forge.DefaultList)
|
||||
// _ = page
|
||||
|
|
@ -31,7 +31,7 @@ var DefaultList = ListOptions{Page: 1, Limit: 50}
|
|||
|
||||
// PagedResult holds a single page of results with metadata.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// page, err := forge.ListPage[types.Repository](ctx, client, path, nil, forge.DefaultList)
|
||||
// _ = page
|
||||
|
|
@ -45,7 +45,7 @@ type PagedResult[T any] struct {
|
|||
// ListPage fetches a single page of results.
|
||||
// Extra query params can be passed via the query map.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// page, err := forge.ListPage[types.Repository](ctx, client, "/api/v1/user/repos", nil, forge.DefaultList)
|
||||
// _ = page
|
||||
|
|
@ -91,7 +91,7 @@ func ListPage[T any](ctx context.Context, c *Client, path string, query map[stri
|
|||
|
||||
// ListAll fetches all pages of results.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// items, err := forge.ListAll[types.Repository](ctx, client, "/api/v1/user/repos", nil)
|
||||
// _ = items
|
||||
|
|
@ -116,7 +116,7 @@ func ListAll[T any](ctx context.Context, c *Client, path string, query map[strin
|
|||
|
||||
// ListIter returns an iterator over all resources across all pages.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// for item, err := range forge.ListIter[types.Repository](ctx, client, "/api/v1/user/repos", nil) {
|
||||
// _, _ = item, err
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
// Params maps path variable names to values.
|
||||
// Example: Params{"owner": "core", "repo": "go-forge"}
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// params := forge.Params{"owner": "core", "repo": "go-forge"}
|
||||
// _ = params
|
||||
|
|
@ -17,7 +17,7 @@ type Params map[string]string
|
|||
|
||||
// ResolvePath substitutes {placeholders} in path with values from params.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// path := forge.ResolvePath("/api/v1/repos/{owner}/{repo}", forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
// _ = path
|
||||
|
|
|
|||
30
pulls.go
30
pulls.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// PullService handles pull request operations within a repository.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Pulls.ListAll(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
|
|
@ -26,6 +26,10 @@ func newPullService(c *Client) *PullService {
|
|||
}
|
||||
|
||||
// Merge merges a pull request. Method is one of "merge", "rebase", "rebase-merge", "squash", "fast-forward-only", "manually-merged".
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Merge(ctx, owner, repo, index, method)
|
||||
func (s *PullService) Merge(ctx context.Context, owner, repo string, index int64, method string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/merge", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
body := map[string]string{"Do": method}
|
||||
|
|
@ -33,24 +37,40 @@ func (s *PullService) Merge(ctx context.Context, owner, repo string, index int64
|
|||
}
|
||||
|
||||
// Update updates a pull request branch with the base branch.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Update(ctx, owner, repo, index)
|
||||
func (s *PullService) Update(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/update", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// ListReviews returns all reviews on a pull request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListReviews(ctx, owner, repo, index)
|
||||
func (s *PullService) ListReviews(ctx context.Context, owner, repo string, index int64) ([]types.PullReview, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return ListAll[types.PullReview](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterReviews returns an iterator over all reviews on a pull request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterReviews(ctx, owner, repo, index)
|
||||
func (s *PullService) IterReviews(ctx context.Context, owner, repo string, index int64) iter.Seq2[types.PullReview, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
return ListIter[types.PullReview](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// SubmitReview creates a new review on a pull request.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.SubmitReview(ctx, owner, repo, index, review)
|
||||
func (s *PullService) SubmitReview(ctx context.Context, owner, repo string, index int64, review map[string]any) (*types.PullReview, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews", pathParams("owner", owner, "repo", repo, "index", int64String(index)))
|
||||
var out types.PullReview
|
||||
|
|
@ -61,6 +81,10 @@ func (s *PullService) SubmitReview(ctx context.Context, owner, repo string, inde
|
|||
}
|
||||
|
||||
// DismissReview dismisses a pull request review.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DismissReview(ctx, owner, repo, index, reviewID, msg)
|
||||
func (s *PullService) DismissReview(ctx context.Context, owner, repo string, index, reviewID int64, msg string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{reviewID}/dismissals", pathParams("owner", owner, "repo", repo, "index", int64String(index), "reviewID", int64String(reviewID)))
|
||||
body := map[string]string{"message": msg}
|
||||
|
|
@ -68,6 +92,10 @@ func (s *PullService) DismissReview(ctx context.Context, owner, repo string, ind
|
|||
}
|
||||
|
||||
// UndismissReview undismisses a pull request review.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.UndismissReview(ctx, owner, repo, index, reviewID)
|
||||
func (s *PullService) UndismissReview(ctx context.Context, owner, repo string, index, reviewID int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{reviewID}/undismissals", pathParams("owner", owner, "repo", repo, "index", int64String(index), "reviewID", int64String(reviewID)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
|
|
|
|||
26
releases.go
26
releases.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// ReleaseService handles release operations within a repository.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Releases.ListAll(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
|
|
@ -26,6 +26,10 @@ func newReleaseService(c *Client) *ReleaseService {
|
|||
}
|
||||
|
||||
// GetByTag returns a release by its tag name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetByTag(ctx, owner, repo, tag)
|
||||
func (s *ReleaseService) GetByTag(ctx context.Context, owner, repo, tag string) (*types.Release, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/tags/{tag}", pathParams("owner", owner, "repo", repo, "tag", tag))
|
||||
var out types.Release
|
||||
|
|
@ -36,24 +40,40 @@ func (s *ReleaseService) GetByTag(ctx context.Context, owner, repo, tag string)
|
|||
}
|
||||
|
||||
// DeleteByTag deletes a release by its tag name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteByTag(ctx, owner, repo, tag)
|
||||
func (s *ReleaseService) DeleteByTag(ctx context.Context, owner, repo, tag string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/tags/{tag}", pathParams("owner", owner, "repo", repo, "tag", tag))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListAssets returns all assets for a release.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListAssets(ctx, owner, repo, releaseID)
|
||||
func (s *ReleaseService) ListAssets(ctx context.Context, owner, repo string, releaseID int64) ([]types.Attachment, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/{releaseID}/assets", pathParams("owner", owner, "repo", repo, "releaseID", int64String(releaseID)))
|
||||
return ListAll[types.Attachment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterAssets returns an iterator over all assets for a release.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterAssets(ctx, owner, repo, releaseID)
|
||||
func (s *ReleaseService) IterAssets(ctx context.Context, owner, repo string, releaseID int64) iter.Seq2[types.Attachment, error] {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/{releaseID}/assets", pathParams("owner", owner, "repo", repo, "releaseID", int64String(releaseID)))
|
||||
return ListIter[types.Attachment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetAsset returns a single asset for a release.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetAsset(ctx, owner, repo, releaseID, assetID)
|
||||
func (s *ReleaseService) GetAsset(ctx context.Context, owner, repo string, releaseID, assetID int64) (*types.Attachment, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/{releaseID}/assets/{assetID}", pathParams("owner", owner, "repo", repo, "releaseID", int64String(releaseID), "assetID", int64String(assetID)))
|
||||
var out types.Attachment
|
||||
|
|
@ -64,6 +84,10 @@ func (s *ReleaseService) GetAsset(ctx context.Context, owner, repo string, relea
|
|||
}
|
||||
|
||||
// DeleteAsset deletes a single asset from a release.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeleteAsset(ctx, owner, repo, releaseID, assetID)
|
||||
func (s *ReleaseService) DeleteAsset(ctx context.Context, owner, repo string, releaseID, assetID int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/releases/{releaseID}/assets/{assetID}", pathParams("owner", owner, "repo", repo, "releaseID", int64String(releaseID), "assetID", int64String(assetID)))
|
||||
return s.client.Delete(ctx, path)
|
||||
|
|
|
|||
38
repos.go
38
repos.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// RepoService handles repository operations.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Repos.ListOrgRepos(ctx, "core")
|
||||
|
|
@ -26,26 +26,46 @@ func newRepoService(c *Client) *RepoService {
|
|||
}
|
||||
|
||||
// ListOrgRepos returns all repositories for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgRepos(ctx, org)
|
||||
func (s *RepoService) ListOrgRepos(ctx context.Context, org string) ([]types.Repository, error) {
|
||||
return ListAll[types.Repository](ctx, s.client, "/api/v1/orgs/"+org+"/repos", nil)
|
||||
}
|
||||
|
||||
// IterOrgRepos returns an iterator over all repositories for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgRepos(ctx, org)
|
||||
func (s *RepoService) IterOrgRepos(ctx context.Context, org string) iter.Seq2[types.Repository, error] {
|
||||
return ListIter[types.Repository](ctx, s.client, "/api/v1/orgs/"+org+"/repos", nil)
|
||||
}
|
||||
|
||||
// ListUserRepos returns all repositories for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListUserRepos(ctx)
|
||||
func (s *RepoService) ListUserRepos(ctx context.Context) ([]types.Repository, error) {
|
||||
return ListAll[types.Repository](ctx, s.client, "/api/v1/user/repos", nil)
|
||||
}
|
||||
|
||||
// IterUserRepos returns an iterator over all repositories for the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterUserRepos(ctx)
|
||||
func (s *RepoService) IterUserRepos(ctx context.Context) iter.Seq2[types.Repository, error] {
|
||||
return ListIter[types.Repository](ctx, s.client, "/api/v1/user/repos", nil)
|
||||
}
|
||||
|
||||
// Fork forks a repository. If org is non-empty, forks into that organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.Fork(ctx, owner, repo, org)
|
||||
func (s *RepoService) Fork(ctx context.Context, owner, repo, org string) (*types.Repository, error) {
|
||||
body := map[string]string{}
|
||||
if org != "" {
|
||||
|
|
@ -60,21 +80,37 @@ func (s *RepoService) Fork(ctx context.Context, owner, repo, org string) (*types
|
|||
}
|
||||
|
||||
// Transfer initiates a repository transfer.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Transfer(ctx, owner, repo, opts)
|
||||
func (s *RepoService) Transfer(ctx context.Context, owner, repo string, opts map[string]any) error {
|
||||
return s.client.Post(ctx, "/api/v1/repos/"+owner+"/"+repo+"/transfer", opts, nil)
|
||||
}
|
||||
|
||||
// AcceptTransfer accepts a pending repository transfer.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AcceptTransfer(ctx, owner, repo)
|
||||
func (s *RepoService) AcceptTransfer(ctx context.Context, owner, repo string) error {
|
||||
return s.client.Post(ctx, "/api/v1/repos/"+owner+"/"+repo+"/transfer/accept", nil, nil)
|
||||
}
|
||||
|
||||
// RejectTransfer rejects a pending repository transfer.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RejectTransfer(ctx, owner, repo)
|
||||
func (s *RepoService) RejectTransfer(ctx context.Context, owner, repo string) error {
|
||||
return s.client.Post(ctx, "/api/v1/repos/"+owner+"/"+repo+"/transfer/reject", nil, nil)
|
||||
}
|
||||
|
||||
// MirrorSync triggers a mirror sync.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.MirrorSync(ctx, owner, repo)
|
||||
func (s *RepoService) MirrorSync(ctx context.Context, owner, repo string) error {
|
||||
return s.client.Post(ctx, "/api/v1/repos/"+owner+"/"+repo+"/mirror-sync", nil, nil)
|
||||
}
|
||||
|
|
|
|||
32
resource.go
32
resource.go
|
|
@ -10,7 +10,7 @@ import (
|
|||
// Resource provides generic CRUD operations for a Forgejo API resource.
|
||||
// T is the resource type, C is the create options type, U is the update options type.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// r := forge.NewResource[types.Issue, types.CreateIssueOption, types.EditIssueOption](client, "/api/v1/repos/{owner}/{repo}/issues/{index}")
|
||||
// _ = r
|
||||
|
|
@ -24,7 +24,7 @@ type Resource[T any, C any, U any] struct {
|
|||
// The path should be the item path (e.g., /repos/{owner}/{repo}/issues/{index}).
|
||||
// The collection path is derived by stripping the last /{placeholder} segment.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// r := forge.NewResource[types.Issue, types.CreateIssueOption, types.EditIssueOption](client, "/api/v1/repos/{owner}/{repo}/issues/{index}")
|
||||
// _ = r
|
||||
|
|
@ -42,21 +42,37 @@ func NewResource[T any, C any, U any](c *Client, path string) *Resource[T, C, U]
|
|||
}
|
||||
|
||||
// List returns a single page of resources.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := r.List(ctx, params, opts)
|
||||
func (r *Resource[T, C, U]) List(ctx context.Context, params Params, opts ListOptions) (*PagedResult[T], error) {
|
||||
return ListPage[T](ctx, r.client, ResolvePath(r.collection, params), nil, opts)
|
||||
}
|
||||
|
||||
// ListAll returns all resources across all pages.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := r.ListAll(ctx, params)
|
||||
func (r *Resource[T, C, U]) ListAll(ctx context.Context, params Params) ([]T, error) {
|
||||
return ListAll[T](ctx, r.client, ResolvePath(r.collection, params), nil)
|
||||
}
|
||||
|
||||
// Iter returns an iterator over all resources across all pages.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = r.Iter(ctx, params)
|
||||
func (r *Resource[T, C, U]) Iter(ctx context.Context, params Params) iter.Seq2[T, error] {
|
||||
return ListIter[T](ctx, r.client, ResolvePath(r.collection, params), nil)
|
||||
}
|
||||
|
||||
// Get returns a single resource by appending id to the path.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := r.Get(ctx, params)
|
||||
func (r *Resource[T, C, U]) Get(ctx context.Context, params Params) (*T, error) {
|
||||
var out T
|
||||
if err := r.client.Get(ctx, ResolvePath(r.path, params), &out); err != nil {
|
||||
|
|
@ -66,6 +82,10 @@ func (r *Resource[T, C, U]) Get(ctx context.Context, params Params) (*T, error)
|
|||
}
|
||||
|
||||
// Create creates a new resource.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := r.Create(ctx, params, body)
|
||||
func (r *Resource[T, C, U]) Create(ctx context.Context, params Params, body *C) (*T, error) {
|
||||
var out T
|
||||
if err := r.client.Post(ctx, ResolvePath(r.collection, params), body, &out); err != nil {
|
||||
|
|
@ -75,6 +95,10 @@ func (r *Resource[T, C, U]) Create(ctx context.Context, params Params, body *C)
|
|||
}
|
||||
|
||||
// Update modifies an existing resource.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := r.Update(ctx, params, body)
|
||||
func (r *Resource[T, C, U]) Update(ctx context.Context, params Params, body *U) (*T, error) {
|
||||
var out T
|
||||
if err := r.client.Patch(ctx, ResolvePath(r.path, params), body, &out); err != nil {
|
||||
|
|
@ -84,6 +108,10 @@ func (r *Resource[T, C, U]) Update(ctx context.Context, params Params, body *U)
|
|||
}
|
||||
|
||||
// Delete removes a resource.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := r.Delete(ctx, params)
|
||||
func (r *Resource[T, C, U]) Delete(ctx context.Context, params Params) error {
|
||||
return r.client.Delete(ctx, ResolvePath(r.path, params))
|
||||
}
|
||||
|
|
|
|||
42
teams.go
42
teams.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// TeamService handles team operations.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Teams.ListMembers(ctx, 42)
|
||||
|
|
@ -26,60 +26,100 @@ func newTeamService(c *Client) *TeamService {
|
|||
}
|
||||
|
||||
// ListMembers returns all members of a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListMembers(ctx, teamID)
|
||||
func (s *TeamService) ListMembers(ctx context.Context, teamID int64) ([]types.User, error) {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/members", pathParams("teamID", int64String(teamID)))
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterMembers returns an iterator over all members of a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterMembers(ctx, teamID)
|
||||
func (s *TeamService) IterMembers(ctx context.Context, teamID int64) iter.Seq2[types.User, error] {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/members", pathParams("teamID", int64String(teamID)))
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddMember adds a user to a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AddMember(ctx, teamID, username)
|
||||
func (s *TeamService) AddMember(ctx context.Context, teamID int64, username string) error {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/members/{username}", pathParams("teamID", int64String(teamID), "username", username))
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveMember removes a user from a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RemoveMember(ctx, teamID, username)
|
||||
func (s *TeamService) RemoveMember(ctx context.Context, teamID int64, username string) error {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/members/{username}", pathParams("teamID", int64String(teamID), "username", username))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListRepos returns all repositories managed by a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListRepos(ctx, teamID)
|
||||
func (s *TeamService) ListRepos(ctx context.Context, teamID int64) ([]types.Repository, error) {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/repos", pathParams("teamID", int64String(teamID)))
|
||||
return ListAll[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepos returns an iterator over all repositories managed by a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterRepos(ctx, teamID)
|
||||
func (s *TeamService) IterRepos(ctx context.Context, teamID int64) iter.Seq2[types.Repository, error] {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/repos", pathParams("teamID", int64String(teamID)))
|
||||
return ListIter[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddRepo adds a repository to a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.AddRepo(ctx, teamID, org, repo)
|
||||
func (s *TeamService) AddRepo(ctx context.Context, teamID int64, org, repo string) error {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/repos/{org}/{repo}", pathParams("teamID", int64String(teamID), "org", org, "repo", repo))
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveRepo removes a repository from a team.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.RemoveRepo(ctx, teamID, org, repo)
|
||||
func (s *TeamService) RemoveRepo(ctx context.Context, teamID int64, org, repo string) error {
|
||||
path := ResolvePath("/api/v1/teams/{teamID}/repos/{org}/{repo}", pathParams("teamID", int64String(teamID), "org", org, "repo", repo))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgTeams returns all teams in an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgTeams(ctx, org)
|
||||
func (s *TeamService) ListOrgTeams(ctx context.Context, org string) ([]types.Team, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/teams", pathParams("org", org))
|
||||
return ListAll[types.Team](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgTeams returns an iterator over all teams in an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgTeams(ctx, org)
|
||||
func (s *TeamService) IterOrgTeams(ctx context.Context, org string) iter.Seq2[types.Team, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/teams", pathParams("org", org))
|
||||
return ListIter[types.Team](ctx, s.client, path, nil)
|
||||
|
|
|
|||
46
users.go
46
users.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// UserService handles user operations.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Users.GetCurrent(ctx)
|
||||
|
|
@ -26,6 +26,10 @@ func newUserService(c *Client) *UserService {
|
|||
}
|
||||
|
||||
// GetCurrent returns the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetCurrent(ctx)
|
||||
func (s *UserService) GetCurrent(ctx context.Context) (*types.User, error) {
|
||||
var out types.User
|
||||
if err := s.client.Get(ctx, "/api/v1/user", &out); err != nil {
|
||||
|
|
@ -35,60 +39,100 @@ func (s *UserService) GetCurrent(ctx context.Context) (*types.User, error) {
|
|||
}
|
||||
|
||||
// ListFollowers returns all followers of a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListFollowers(ctx, username)
|
||||
func (s *UserService) ListFollowers(ctx context.Context, username string) ([]types.User, error) {
|
||||
path := ResolvePath("/api/v1/users/{username}/followers", pathParams("username", username))
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFollowers returns an iterator over all followers of a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterFollowers(ctx, username)
|
||||
func (s *UserService) IterFollowers(ctx context.Context, username string) iter.Seq2[types.User, error] {
|
||||
path := ResolvePath("/api/v1/users/{username}/followers", pathParams("username", username))
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// ListFollowing returns all users that a user is following.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListFollowing(ctx, username)
|
||||
func (s *UserService) ListFollowing(ctx context.Context, username string) ([]types.User, error) {
|
||||
path := ResolvePath("/api/v1/users/{username}/following", pathParams("username", username))
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFollowing returns an iterator over all users that a user is following.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterFollowing(ctx, username)
|
||||
func (s *UserService) IterFollowing(ctx context.Context, username string) iter.Seq2[types.User, error] {
|
||||
path := ResolvePath("/api/v1/users/{username}/following", pathParams("username", username))
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Follow follows a user as the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Follow(ctx, username)
|
||||
func (s *UserService) Follow(ctx context.Context, username string) error {
|
||||
path := ResolvePath("/api/v1/user/following/{username}", pathParams("username", username))
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unfollow unfollows a user as the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Unfollow(ctx, username)
|
||||
func (s *UserService) Unfollow(ctx context.Context, username string) error {
|
||||
path := ResolvePath("/api/v1/user/following/{username}", pathParams("username", username))
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListStarred returns all repositories starred by a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListStarred(ctx, username)
|
||||
func (s *UserService) ListStarred(ctx context.Context, username string) ([]types.Repository, error) {
|
||||
path := ResolvePath("/api/v1/users/{username}/starred", pathParams("username", username))
|
||||
return ListAll[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterStarred returns an iterator over all repositories starred by a user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterStarred(ctx, username)
|
||||
func (s *UserService) IterStarred(ctx context.Context, username string) iter.Seq2[types.Repository, error] {
|
||||
path := ResolvePath("/api/v1/users/{username}/starred", pathParams("username", username))
|
||||
return ListIter[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Star stars a repository as the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Star(ctx, owner, repo)
|
||||
func (s *UserService) Star(ctx context.Context, owner, repo string) error {
|
||||
path := ResolvePath("/api/v1/user/starred/{owner}/{repo}", pathParams("owner", owner, "repo", repo))
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unstar unstars a repository as the authenticated user.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.Unstar(ctx, owner, repo)
|
||||
func (s *UserService) Unstar(ctx context.Context, owner, repo string) error {
|
||||
path := ResolvePath("/api/v1/user/starred/{owner}/{repo}", pathParams("owner", owner, "repo", repo))
|
||||
return s.client.Delete(ctx, path)
|
||||
|
|
|
|||
14
webhooks.go
14
webhooks.go
|
|
@ -10,7 +10,7 @@ import (
|
|||
// WebhookService handles webhook (hook) operations within a repository.
|
||||
// Embeds Resource for standard CRUD on /api/v1/repos/{owner}/{repo}/hooks/{id}.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Webhooks.ListAll(ctx, forge.Params{"owner": "core", "repo": "go-forge"})
|
||||
|
|
@ -27,18 +27,30 @@ func newWebhookService(c *Client) *WebhookService {
|
|||
}
|
||||
|
||||
// TestHook triggers a test delivery for a webhook.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.TestHook(ctx, owner, repo, id)
|
||||
func (s *WebhookService) TestHook(ctx context.Context, owner, repo string, id int64) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/hooks/{id}/tests", pathParams("owner", owner, "repo", repo, "id", int64String(id)))
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// ListOrgHooks returns all webhooks for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListOrgHooks(ctx, org)
|
||||
func (s *WebhookService) ListOrgHooks(ctx context.Context, org string) ([]types.Hook, error) {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/hooks", pathParams("org", org))
|
||||
return ListAll[types.Hook](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgHooks returns an iterator over all webhooks for an organisation.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _ = s.IterOrgHooks(ctx, org)
|
||||
func (s *WebhookService) IterOrgHooks(ctx context.Context, org string) iter.Seq2[types.Hook, error] {
|
||||
path := ResolvePath("/api/v1/orgs/{org}/hooks", pathParams("org", org))
|
||||
return ListIter[types.Hook](ctx, s.client, path, nil)
|
||||
|
|
|
|||
22
wiki.go
22
wiki.go
|
|
@ -9,7 +9,7 @@ import (
|
|||
// WikiService handles wiki page operations for a repository.
|
||||
// No Resource embedding — custom endpoints for wiki CRUD.
|
||||
//
|
||||
// Usage:
|
||||
// Usage example:
|
||||
//
|
||||
// f := forge.NewForge("https://forge.lthn.ai", "token")
|
||||
// _, err := f.Wiki.ListPages(ctx, "core", "go-forge")
|
||||
|
|
@ -22,6 +22,10 @@ func newWikiService(c *Client) *WikiService {
|
|||
}
|
||||
|
||||
// ListPages returns all wiki page metadata for a repository.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.ListPages(ctx, owner, repo)
|
||||
func (s *WikiService) ListPages(ctx context.Context, owner, repo string) ([]types.WikiPageMetaData, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/wiki/pages", pathParams("owner", owner, "repo", repo))
|
||||
var out []types.WikiPageMetaData
|
||||
|
|
@ -32,6 +36,10 @@ func (s *WikiService) ListPages(ctx context.Context, owner, repo string) ([]type
|
|||
}
|
||||
|
||||
// GetPage returns a single wiki page by name.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.GetPage(ctx, owner, repo, pageName)
|
||||
func (s *WikiService) GetPage(ctx context.Context, owner, repo, pageName string) (*types.WikiPage, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/wiki/page/{pageName}", pathParams("owner", owner, "repo", repo, "pageName", pageName))
|
||||
var out types.WikiPage
|
||||
|
|
@ -42,6 +50,10 @@ func (s *WikiService) GetPage(ctx context.Context, owner, repo, pageName string)
|
|||
}
|
||||
|
||||
// CreatePage creates a new wiki page.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.CreatePage(ctx, owner, repo, opts)
|
||||
func (s *WikiService) CreatePage(ctx context.Context, owner, repo string, opts *types.CreateWikiPageOptions) (*types.WikiPage, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/wiki/new", pathParams("owner", owner, "repo", repo))
|
||||
var out types.WikiPage
|
||||
|
|
@ -52,6 +64,10 @@ func (s *WikiService) CreatePage(ctx context.Context, owner, repo string, opts *
|
|||
}
|
||||
|
||||
// EditPage updates an existing wiki page.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// _, err := s.EditPage(ctx, owner, repo, pageName, opts)
|
||||
func (s *WikiService) EditPage(ctx context.Context, owner, repo, pageName string, opts *types.CreateWikiPageOptions) (*types.WikiPage, error) {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/wiki/page/{pageName}", pathParams("owner", owner, "repo", repo, "pageName", pageName))
|
||||
var out types.WikiPage
|
||||
|
|
@ -62,6 +78,10 @@ func (s *WikiService) EditPage(ctx context.Context, owner, repo, pageName string
|
|||
}
|
||||
|
||||
// DeletePage removes a wiki page.
|
||||
//
|
||||
// Usage example:
|
||||
//
|
||||
// err := s.DeletePage(ctx, owner, repo, pageName)
|
||||
func (s *WikiService) DeletePage(ctx context.Context, owner, repo, pageName string) error {
|
||||
path := ResolvePath("/api/v1/repos/{owner}/{repo}/wiki/page/{pageName}", pathParams("owner", owner, "repo", repo, "pageName", pageName))
|
||||
return s.client.Delete(ctx, path)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue