( name: string, isTaken: (slug: string) => Promise<boolean>, )
| 171 | * back to `team-<discriminator>` handles. |
| 172 | */ |
| 173 | export const generateOrgSlug = async ( |
| 174 | name: string, |
| 175 | isTaken: (slug: string) => Promise<boolean>, |
| 176 | ): Promise<string> => { |
| 177 | const base = slugifyOrgName(name) ?? "team"; |
| 178 | // Leave room for the "-xxxx" discriminator within the 48-char budget. |
| 179 | const trimmed = base.slice(0, 48 - DISCRIMINATOR_LENGTH - 1).replace(/-+$/g, ""); |
| 180 | if (isValidOrgSlug(trimmed) && !(await isTaken(trimmed))) return trimmed; |
| 181 | for (let attempt = 0; attempt < 32; attempt++) { |
| 182 | const candidate = `${trimmed}-${discriminator()}`; |
| 183 | if (isValidOrgSlug(candidate) && !(await isTaken(candidate))) return candidate; |
| 184 | } |
| 185 | // Practically unreachable (32 misses on a ~1M space means isTaken is |
| 186 | // broken); a longer random handle beats looping forever. |
| 187 | return `team-${discriminator()}${discriminator()}`; |
| 188 | }; |
no test coverage detected