Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions cmd/onecli/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import (
"github.com/onecli/onecli-cli/pkg/validate"
)

// configureResult is the structured response after configuring an app.
type configureResult struct {
App string `json:"app"`
Status string `json:"status"`
}

// AppsCmd is the `onecli apps` command group.
type AppsCmd struct {
List AppsListCmd `cmd:"" help:"List all apps with config and connection status."`
Get AppsGetCmd `cmd:"" help:"Get a single app with setup guidance."`
Configure AppsConfigureCmd `cmd:"" help:"Save OAuth credentials (BYOC) for a provider."`
Remove AppsRemoveCmd `cmd:"" help:"Remove OAuth credentials for a provider."`
Disconnect AppsDisconnectCmd `cmd:"" help:"Disconnect an app connection."`
Expand Down Expand Up @@ -42,6 +49,34 @@ func (c *AppsListCmd) Run(out *output.Writer) error {
return out.WriteFiltered(apps, c.Fields)
}

// AppsGetCmd is `onecli apps get`.
type AppsGetCmd struct {
Provider string `required:"" help:"Provider name (e.g. 'github', 'gmail')."`
Fields string `optional:"" help:"Comma-separated list of fields to include in output."`
}

func (c *AppsGetCmd) Run(out *output.Writer) error {
if err := validate.ResourceID(c.Provider); err != nil {
return fmt.Errorf("invalid provider: %w", err)
}

client, err := newClient()
if err != nil {
return err
}
app, err := client.GetApp(newContext(), c.Provider)
if err != nil {
return err
}

if app.Hint != "" {
out.SetHint(app.Hint)
app.Hint = ""
}

return out.WriteFiltered(app, c.Fields)
}

// AppsConfigureCmd is `onecli apps configure`.
type AppsConfigureCmd struct {
Provider string `required:"" help:"Provider name (e.g. 'github', 'gmail')."`
Expand Down Expand Up @@ -85,9 +120,18 @@ func (c *AppsConfigureCmd) Run(out *output.Writer) error {
return err
}

return out.Write(map[string]string{
"status": "configured",
"provider": c.Provider,
app, err := client.GetApp(newContext(), c.Provider)
if err != nil {
return err
}

if app.Hint != "" {
out.SetHint(app.Hint)
}

return out.Write(configureResult{
App: c.Provider,
Status: "configured",
})
}

Expand Down
3 changes: 3 additions & 0 deletions cmd/onecli/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ func (cmd *HelpCmd) Run(out *output.Writer) error {
{Name: "--id", Required: true, Description: "ID of the secret to delete."},
}},
{Name: "apps list", Description: "List all apps with config and connection status."},
{Name: "apps get", Description: "Get a single app with setup guidance.", Args: []ArgInfo{
{Name: "--provider", Required: true, Description: "Provider name (e.g. 'github', 'gmail')."},
}},
{Name: "apps configure", Description: "Save OAuth credentials (BYOC) for a provider.", Args: []ArgInfo{
{Name: "--provider", Required: true, Description: "Provider name (e.g. 'github', 'gmail')."},
{Name: "--client-id", Required: true, Description: "OAuth client ID."},
Expand Down
12 changes: 11 additions & 1 deletion internal/api/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"net/http"
)

// App represents an app from the unified /api/apps listing.
// App represents an app from the /api/apps endpoints.
type App struct {
ID string `json:"id"`
Name string `json:"name"`
Expand All @@ -15,6 +15,7 @@ type App struct {
Configurable bool `json:"configurable"`
Config *AppConfig `json:"config"`
Connection *AppConnection `json:"connection"`
Hint string `json:"hint,omitempty"`
}

// AppConfig is the BYOC credential configuration status.
Expand Down Expand Up @@ -45,6 +46,15 @@ func (c *Client) ListApps(ctx context.Context) ([]App, error) {
return apps, nil
}

// GetApp returns a single app by provider name.
func (c *Client) GetApp(ctx context.Context, provider string) (*App, error) {
var app App
if err := c.do(ctx, http.MethodGet, "/api/apps/"+provider, nil, &app); err != nil {
return nil, fmt.Errorf("getting app: %w", err)
}
return &app, nil
}

// ConfigureApp saves BYOC credentials for a provider.
func (c *Client) ConfigureApp(ctx context.Context, provider string, input ConfigAppInput) error {
var resp SuccessResponse
Expand Down
Loading