55 "encoding/json"
66 "errors"
77 "fmt"
8+ "io"
89 "time"
910
1011 tea "charm.land/bubbletea/v2"
@@ -16,16 +17,24 @@ import (
1617)
1718
1819// resolveTarget maps a short code and login state onto a stats surface.
19- // Logged in with a code, the alias resolves to an owned link's url id;
20- // a 404 means the link isn't yours (or doesn't exist), so it falls back
21- // to the public endpoint, which answers for anyone's public link.
22- func resolveTarget (ctx context.Context , client * api.Client , code string , loggedIn bool ) (stats.Target , error ) {
20+ // Logged in with a code, the alias resolves to an owned link's url id on
21+ // the given domain (empty means the system default). On a 404 with
22+ // --domain set there is nowhere to fall back to — the public endpoint
23+ // serves only default-domain links — so it errors instead of silently
24+ // showing a different link's stats. Without --domain the code may still
25+ // be someone else's public default-domain link, so it falls back to the
26+ // public endpoint, announcing the switch on errOut.
27+ func resolveTarget (ctx context.Context , client * api.Client , code , domain , defaultDomain string , loggedIn bool , errOut io.Writer ) (stats.Target , error ) {
2328 switch {
2429 case code == "" :
2530 return stats.Target {Kind : stats .KindAccount }, nil
2631 case loggedIn :
27- u , err := client .ResolveAlias (ctx , code )
32+ u , err := client .ResolveAlias (ctx , code , domain )
2833 if api .IsNotFound (err ) {
34+ if domain != "" {
35+ return stats.Target {}, fmt .Errorf ("%s on %s is not one of your links — public stats cover only %s links" , code , domain , defaultDomain )
36+ }
37+ fmt .Fprintf (errOut , "note: %s isn't one of your links — showing public stats for %s/%s\n " , code , defaultDomain , code )
2938 return stats.Target {Kind : stats .KindPublicLink , Alias : code }, nil
3039 }
3140 if err != nil {
@@ -38,7 +47,7 @@ func resolveTarget(ctx context.Context, client *api.Client, code string, loggedI
3847}
3948
4049func newStatsCmd () * cobra.Command {
41- var from , to , tz string
50+ var from , to , tz , domain string
4251 var plain bool
4352 cmd := & cobra.Command {
4453 Use : "stats [short-code]" ,
@@ -75,7 +84,11 @@ With a short code, shows that link — public stats work without login.`,
7584 if ! loggedIn && code == "" {
7685 return fmt .Errorf ("not logged in — pass a short code for public stats, or run `spoo auth login`" )
7786 }
78- target , err := resolveTarget (cmd .Context (), d .client , code , loggedIn )
87+ defaultDomain := apiHost (d .cfg .APIBase )
88+ if domain != "" && ! loggedIn {
89+ return fmt .Errorf ("--domain requires login — public stats cover only %s links" , defaultDomain )
90+ }
91+ target , err := resolveTarget (cmd .Context (), d .client , code , domain , defaultDomain , loggedIn , cmd .ErrOrStderr ())
7992 if err != nil {
8093 return err
8194 }
@@ -132,5 +145,7 @@ With a short code, shows that link — public stats work without login.`,
132145 cmd .Flags ().StringVar (& to , "to" , "" , "end date, ISO 8601 (static report; default: now)" )
133146 cmd .Flags ().StringVar (& tz , "tz" , "" , "IANA timezone for time buckets (default UTC)" )
134147 cmd .Flags ().BoolVar (& plain , "plain" , false , "print the static report instead of the dashboard" )
148+ cmd .Flags ().StringVar (& domain , "domain" , "" , "the link is on one of your custom domains" )
149+ flagComp (cmd , "domain" , completeDomain )
135150 return cmd
136151}
0 commit comments