(name: string)
| 135 | * names, etc.) — callers fall back to a generated handle. |
| 136 | */ |
| 137 | export const slugifyOrgName = (name: string): string | null => { |
| 138 | const slug = name |
| 139 | .normalize("NFKD") |
| 140 | .replace(/\p{M}+/gu, "") |
| 141 | .toLowerCase() |
| 142 | .replace(/[^a-z0-9]+/g, "-") |
| 143 | .replace(/^-+|-+$/g, "") |
| 144 | .slice(0, 48) |
| 145 | .replace(/-+$/g, ""); |
| 146 | if (slug.length < 2 || !ORG_SLUG_PATTERN.test(slug)) return null; |
| 147 | return slug; |
| 148 | }; |
| 149 | |
| 150 | // Discriminator alphabet: lowercase base32 without the look-alikes (0/o, 1/l) |
| 151 | // so a slug read aloud or retyped from a screenshot survives the round trip. |
no test coverage detected