INNER CODE UNIT · TypeScript
personEmail
rowboatlabs/rowboat · apps/harbor/packages/server/src/connectors/attio/index.ts:18
function personEmail(args: string): string {
const parts = args.trim().split('@');
if (parts.length !== 2 || /[\s/:?#%\\]/.test(parts[1]!)) throw new UsageError('Give one email address, such as jane@acme.com.');
const email = `${parts[0]}@${domainToASCII(parts[1]!)}`.toLowerCase();
if (!z.email().safeParse(email).success || email.length > 254 || parts[0]!.length > 64) {
throw new UsageError('Give one email address, such as jane@acme.com.');
}
return email;
}
// Escaped Markdown alone still matches Spaces' mention grammar; entities keep
// CRM text from addressing members or agents (spec §8 Attio, 2026-10-12).
function plainText(value: string, limit: number): string {
const flat = value.replace(/\s+/g, ' ').trim();
const text = flat.length > limit ? `${flat.slice(0, limit)}…` : flat;
return text.replace(/[&<>\[\]`*_\\|()#!]/g, (char) => `&#${char.charCodeAt(0)};`);
}