| 1 | package console |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | |
| 6 | "github.com/carlosframework/platform/internal/domains" |
| 7 | ) |
| 8 | |
| 9 | // matchAccounts resolves one path/flag segment against the accounts the |
| 10 | // VIEWER belongs to, matching it as a sqid or a name — symmetrically, with |
| 11 | // no precedence between the two spaces. Precedence is how a reference |
| 12 | // silently changes meaning the day a colliding account appears; a multi- |
| 13 | // match is returned whole so the caller can be loud instead (picker page, |
| 14 | // CLI error). Names match case-insensitively; an account whose name equals |
| 15 | // its own sqid still counts once. |
| 16 | // |
| 17 | // The returned pointers address accts, so each match carries whatever |
| 18 | // AccountsFor filled in — the viewer's Role included. |
| 19 | func matchAccounts(accts []Account, seg string) []*Account { |
| 20 | var out []*Account |
| 21 | for i := range accts { |
| 22 | if accts[i].Sqid == seg || strings.EqualFold(accts[i].Name, seg) { |
| 23 | out = append(out, &accts[i]) |
| 24 | } |
| 25 | } |
| 26 | return out |
| 27 | } |
| 28 | |
| 29 | // preferredSeg is the path segment the console GENERATES for an account: |
| 30 | // its name, when the name is slug-shaped and resolves uniquely among the |
| 31 | // viewer's own accounts; the sqid otherwise. Links and redirects use it — |
| 32 | // forms always post to the sqid path (page.Base), because a mutation must |
| 33 | // name its target exactly and prettiness is for links. |
| 34 | func preferredSeg(accts []Account, a *Account) string { |
| 35 | if !domains.ValidAccountName(a.Name) { |
| 36 | return a.Sqid |
| 37 | } |
| 38 | for i := range accts { |
| 39 | if accts[i].ID == a.ID { |
| 40 | continue |
| 41 | } |
| 42 | if strings.EqualFold(accts[i].Name, a.Name) || accts[i].Sqid == a.Name { |
| 43 | return a.Sqid |
| 44 | } |
| 45 | } |
| 46 | return a.Name |
| 47 | } |
| 48 | |