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
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.24.0
require github.com/urfave/cli/v3 v3.0.0-alpha9.2 // direct

require (
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260202165838-5bd92a1e5d53.2
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260202165838-5bd92a1e5d53.1
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260323160652-4be687fa490b.2
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260323160652-4be687fa490b.1
connectrpc.com/connect v1.19.1
github.com/briandowns/spinner v1.23.2
github.com/fatih/color v1.18.0
Expand All @@ -26,6 +26,7 @@ require (

require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 // indirect
buf.build/gen/go/gnostic/gnostic/protocolbuffers/go v1.36.11-20230414000709-087bc8072ce4.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1 h1:j9yeqTWEFrtimt8Nng2MIeRrpoCvQzM9/g25XTvqUGg=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20251209175733-2a1774d88802.1/go.mod h1:tvtbpgaVXZX4g6Pn+AnzFycuRK3MOz5HJfEGeEllXYM=
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260202165838-5bd92a1e5d53.2 h1:MeP+r7GwYHWKSMa1ltvtRNwzT+gCyHIYCEpNxWeNwS4=
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260202165838-5bd92a1e5d53.2/go.mod h1:W/PtF1QguqXdSkOHAD0VAOTMNfuESeNOdR2cF/CWeOQ=
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260202165838-5bd92a1e5d53.1 h1:vw4PznfU8x7XrFtc/HHPjWfxNnFExtaSwrPS8cEKq+w=
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260202165838-5bd92a1e5d53.1/go.mod h1:pZsKB5l3aT2mKtGkAZTC8pXhTptdfyYwFGCyH+KVfOM=
buf.build/gen/go/gnostic/gnostic/protocolbuffers/go v1.36.11-20230414000709-087bc8072ce4.1 h1:t8f+WWZ5WNrZaP5zrpWD8f1tKU7eelJMbIAT9FRX558=
buf.build/gen/go/gnostic/gnostic/protocolbuffers/go v1.36.11-20230414000709-087bc8072ce4.1/go.mod h1:/t9AeRQQp2iNkiGHDLfHLW3SzNpYpNPGRZ+Ih8+SOUs=
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260323160652-4be687fa490b.2 h1:AHDJQUgykCBDBE8qx4ewHxk4q29BYin4I5k2VZBJoSI=
buf.build/gen/go/openstatus/api/connectrpc/gosimple v1.19.1-20260323160652-4be687fa490b.2/go.mod h1:M+ceX35kH8wh3cgoFD8o2fNVedIx8NB9LWV7Z0ObO6Y=
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260323160652-4be687fa490b.1 h1:sTK/97BsCzbBtqydnKAyRduWLbm1U7LbOk+hAzOikhs=
buf.build/gen/go/openstatus/api/protocolbuffers/go v1.36.11-20260323160652-4be687fa490b.1/go.mod h1:GRsD/In1AV3/RC92zWVAjBpj57hJIQm7Rph0rLOYYPg=
connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14=
connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w=
github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w=
Expand Down
21 changes: 21 additions & 0 deletions internal/statuspage/statuspage.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ func componentTypeToString(t status_pagev1.PageComponentType) string {
}
}

func localeToString(l status_pagev1.Locale) string {
switch l {
case status_pagev1.Locale_LOCALE_EN:
return "en"
case status_pagev1.Locale_LOCALE_FR:
return "fr"
case status_pagev1.Locale_LOCALE_DE:
return "de"
default:
return "unknown"
}
}

func localesToStrings(locales []status_pagev1.Locale) []string {
result := make([]string, 0, len(locales))
for _, l := range locales {
result = append(result, localeToString(l))
}
return result
}

func StatusPageCmd() *cli.Command {
return &cli.Command{
Name: "status-page",
Expand Down
48 changes: 28 additions & 20 deletions internal/statuspage/statuspage_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ import (
)

type statusPageDetail struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
URL string `json:"url"`
Published bool `json:"published"`
AccessType string `json:"access_type"`
Theme string `json:"theme"`
HomepageURL string `json:"homepage_url,omitempty"`
ContactURL string `json:"contact_url,omitempty"`
Components []statusPageComponent `json:"components,omitempty"`
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
URL string `json:"url"`
Published bool `json:"published"`
AccessType string `json:"access_type"`
Theme string `json:"theme"`
DefaultLocale string `json:"default_locale"`
Locales []string `json:"locales,omitempty"`
HomepageURL string `json:"homepage_url,omitempty"`
ContactURL string `json:"contact_url,omitempty"`
Components []statusPageComponent `json:"components,omitempty"`
}

type statusPageComponent struct {
Expand Down Expand Up @@ -109,16 +111,18 @@ func GetStatusPageInfo(ctx context.Context, client status_pagev1connect.StatusPa

if output.IsJSONOutput() {
detail := statusPageDetail{
ID: page.GetId(),
Title: page.GetTitle(),
Description: page.GetDescription(),
URL: pageURL,
Published: page.GetPublished(),
AccessType: accessTypeToString(page.GetAccessType()),
Theme: themeToString(page.GetTheme()),
HomepageURL: page.GetHomepageUrl(),
ContactURL: page.GetContactUrl(),
Components: comps,
ID: page.GetId(),
Title: page.GetTitle(),
Description: page.GetDescription(),
URL: pageURL,
Published: page.GetPublished(),
AccessType: accessTypeToString(page.GetAccessType()),
Theme: themeToString(page.GetTheme()),
DefaultLocale: localeToString(page.GetDefaultLocale()),
Locales: localesToStrings(page.GetLocales()),
HomepageURL: page.GetHomepageUrl(),
ContactURL: page.GetContactUrl(),
Components: comps,
}
return output.PrintJSON(detail)
}
Expand Down Expand Up @@ -162,6 +166,10 @@ func GetStatusPageInfo(ctx context.Context, client status_pagev1connect.StatusPa

data = append(data, []string{"Access Type", accessTypeToString(page.GetAccessType())})
data = append(data, []string{"Theme", themeToString(page.GetTheme())})
data = append(data, []string{"Default Locale", localeToString(page.GetDefaultLocale())})
if locales := page.GetLocales(); len(locales) > 0 {
data = append(data, []string{"Locales", strings.Join(localesToStrings(locales), ", ")})
}

if page.GetHomepageUrl() != "" {
data = append(data, []string{"Homepage URL", page.GetHomepageUrl()})
Expand Down
13 changes: 11 additions & 2 deletions internal/statuspage/statuspage_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"strings"

status_pagev1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/status_page/v1"
"buf.build/gen/go/openstatus/api/connectrpc/gosimple/openstatus/status_page/v1/status_pagev1connect"
Expand Down Expand Up @@ -42,7 +43,7 @@ func ListStatusPages(ctx context.Context, client status_pagev1connect.StatusPage
entries = append(entries, statusPageListEntry{
ID: p.GetId(),
Title: p.GetTitle(),
URL: "https://" + p.GetSlug() + ".openstatus.dev",
URL: statusPageURL(p),
})
}
return output.PrintJSON(entries)
Expand All @@ -65,14 +66,22 @@ func ListStatusPages(ctx context.Context, client status_pagev1connect.StatusPage
tbl.AddRow(
p.GetId(),
p.GetTitle(),
"https://"+p.GetSlug()+".openstatus.dev",
statusPageURL(p),
)
}

tbl.Print()
return nil
}

func statusPageURL(p *status_pagev1.StatusPageSummary) string {
if d := p.GetCustomDomain(); d != "" {
d = strings.TrimPrefix(strings.TrimPrefix(d, "https://"), "http://")
return "https://" + d
}
return "https://" + p.GetSlug() + ".openstatus.dev"
}

func ListStatusPagesWithHTTPClient(ctx context.Context, httpClient *http.Client, apiKey string, limit int) error {
client := NewStatusPageClientWithHTTPClient(httpClient, apiKey)
return ListStatusPages(ctx, client, limit, nil)
Expand Down
27 changes: 27 additions & 0 deletions internal/statuspage/statuspage_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ func Test_ListStatusPages(t *testing.T) {
}
})

t.Run("Displays custom domain when set", func(t *testing.T) {
body := `{"statusPages":[{"id":"1","title":"My Status Page","slug":"my-page","customDomain":"status.example.com","published":true,"createdAt":"2026-01-01T00:00:00Z","updatedAt":"2026-01-01T00:00:00Z"}],"totalSize":1}`
r := io.NopCloser(bytes.NewReader([]byte(body)))

interceptor := &interceptorHTTPClient{
f: func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: r,
Header: http.Header{
"Content-Type": []string{"application/json"},
},
}, nil
},
}

var bf bytes.Buffer
log.SetOutput(&bf)
t.Cleanup(func() {
log.SetOutput(os.Stderr)
})
err := statuspage.ListStatusPagesWithHTTPClient(context.Background(), interceptor.GetHTTPClient(), "test-token", 0)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
})

t.Run("Returns empty list", func(t *testing.T) {
body := `{"statusPages":[],"totalSize":0}`
r := io.NopCloser(bytes.NewReader([]byte(body)))
Expand Down
Loading