Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Merge workspace invitations: nobody joins a workspace without saying yes, people are found by username, your own invites can bring someone in, and nobody is left without a workspace (identity 0040) | 1 | /** |
| 2 | * Inviting someone into a workspace from People: who was typed, and what | |
| 3 | * to search for as they type. Search finds people by username or name and | |
| 4 | * shows only what a profile shows (a username, a name, an avatar), never an | |
| 5 | * email address. No Workers or React imports, so it can be tested under Node. | |
| 6 | */ | |
| 7 | ||
| 8 | /** Where the invite form asks for people as someone types (routes/people-json.ts). */ | |
| 9 | export const PEOPLE_SEARCH_PATH = "/-/people.json"; | |
| 10 | ||
| 11 | /** The longest query the search takes. */ | |
| 12 | const MAX_QUERY = 80; | |
| 13 | ||
| 14 | /** Whether `text` reads as an email address rather than a username. */ | |
| 15 | export function looksLikeEmail(text: string): boolean { | |
| 16 | const at = text.trim().indexOf("@"); | |
| 17 | return at > 0; | |
| 18 | } | |
| 19 | ||
| 20 | /** | |
| 21 | * What to search for as someone types `text`: the text without a leading | |
| 22 | * `@`, or null for nothing to search (empty, or an email address, which is | |
| 23 | * never looked up). | |
| 24 | */ | |
| 25 | export function peopleQuery(text: string): string | null { | |
| 26 | const trimmed = text.trim(); | |
| 27 | if (!trimmed || looksLikeEmail(trimmed)) return null; | |
| 28 | const query = trimmed.replace(/^@+/, "").slice(0, MAX_QUERY); | |
| 29 | return query ? query : null; | |
| 30 | } | |
| 31 | ||
| 32 | /** Who the invite form names: an email address, or a username. Null for nothing. */ | |
| 33 | export function inviteTarget(text: string): { email: string } | { username: string } | null { | |
| 34 | const trimmed = text.trim(); | |
| 35 | if (!trimmed) return null; | |
| 36 | if (looksLikeEmail(trimmed)) return { email: trimmed }; | |
| 37 | const username = trimmed.replace(/^@+/, "").toLowerCase(); | |
| 38 | return username ? { username } : null; | |
| 39 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.