Saltar al contenido principal

sanitizeEmail

Paquete: @tiendana/utils

Limpia direcciones de email: recorta espacios y, solo si el email no cumple Patterns.EMAIL, remueve caracteres fuera de un conjunto permitido. No valida: el resultado puede seguir siendo inválido.

Características​

✅ Elimina espacios al inicio y final
✅ Retorna sin cambios un email que cumple Patterns.EMAIL
✅ Remueve caracteres fuera de a-zA-Z0-9_, / a @ y . si no cumple
✅ Case-sensitive (no cambia mayúsculas)

Firma​

function sanitizeEmail(email: string): string

Parámetros​

ParámetroTipoDescripciónRequerido
emailstringDirección de email a sanitizar✅

Retorno​

Tipo: string

  • El email recortado (trim) y sin más cambios si cumple Patterns.EMAIL
  • Si no lo cumple, el email recortado y sin los caracteres que no estén permitidos (puede seguir siendo inválido)

Ejemplos de Uso​

Sanitización Básica​

import { sanitizeEmail } from '@tiendana/utils';

sanitizeEmail(' juan@example.com ');
// 'juan@example.com'

sanitizeEmail('juan@example.com');
// 'juan@example.com'

Email con Caracteres Inválidos​

sanitizeEmail('juan perez@example.com');
// 'juanperez@example.com'

sanitizeEmail('juan @ex ample.com');
// 'juan@example.com'

sanitizeEmail('(juan)@example.com');
// 'juan@example.com'
#, !, $ y + son válidos en el local-part

Patterns.EMAIL acepta ! # $ % & ' * + / = ? ^ { | } ~ (y la comilla invertida) antes de la @, así que un email que solo los contiene se retorna intacto:

sanitizeEmail('juan#$%@example.com');   // 'juan#$%@example.com'
sanitizeEmail('user!name@domain.com'); // 'user!name@domain.com'
sanitizeEmail('juan+tag@example.com'); // 'juan+tag@example.com'
sanitizeEmail('test@@example.com'); // 'test@@example.com' (no se colapsan las @)

Validación de Form Input​

function validateEmailInput(input: string): string {
const cleaned = sanitizeEmail(input);

// Validar adicionalmente con Patterns.EMAIL
if (!Patterns.EMAIL.test(cleaned)) {
throw new Error('Email inválido después de sanitizar');
}

return cleaned;
}

Normalizar Email de Usuario​

interface UserRegistration {
name: string;
email: string;
password: string;
}

function processRegistration(data: UserRegistration) {
return {
...data,
email: sanitizeEmail(data.email)
};
}

const user = processRegistration({
name: 'Juan',
email: ' juan@example.com ',
password: 'pass123'
});
// user.email: 'juan@example.com'

Limpiar Lista de Emails​

function sanitizeEmailList(emails: string[]): string[] {
return emails.map(email => sanitizeEmail(email));
}

const emails = [
' user1@example.com ',
'user 2@example.com',
'user3@example.com'
];

const cleaned = sanitizeEmailList(emails);
// ['user1@example.com', 'user2@example.com', 'user3@example.com']

Importar Contactos​

function importContacts(csvData: string): string[] {
return csvData
.split('\n')
.map(line => line.split(',')[1]) // Columna email
.map(email => sanitizeEmail(email))
.filter(email => Patterns.EMAIL.test(email)); // Solo emails válidos
}

Form Submit​

function handleEmailSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();

const formData = new FormData(event.currentTarget);
const rawEmail = formData.get('email') as string;
const cleanEmail = sanitizeEmail(rawEmail);

if (Patterns.EMAIL.test(cleanEmail)) {
// Procesar email válido
submitEmail(cleanEmail);
} else {
// Mostrar error
alert('Email inválido');
}
}

API Request​

async function subscribeNewsletter(email: string) {
const sanitized = sanitizeEmail(email);

const response = await fetch('/api/newsletter/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: sanitized })
});

return response.json();
}

Validación en Tiempo Real​

function EmailInput() {
const [email, setEmail] = useState('');
const [error, setError] = useState('');

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
setEmail(value);

const cleaned = sanitizeEmail(value);

if (value !== cleaned) {
setError('Email contiene caracteres inválidos');
} else if (!Patterns.EMAIL.test(cleaned)) {
setError('Formato de email inválido');
} else {
setError('');
}
};

return (
<div>
<input type="email" value={email} onChange={handleChange} />
{error && <span className="error">{error}</span>}
</div>
);
}

Deduplicación​

function deduplicateEmails(emails: string[]): string[] {
const sanitized = emails.map(email => sanitizeEmail(email));
return [...new Set(sanitized)];
}

const emails = [
'juan@example.com',
' juan@example.com ',
'JUAN@EXAMPLE.COM' // ⚠️ No convierte a lowercase
];

deduplicateEmails(emails);
// ['juan@example.com', 'JUAN@EXAMPLE.COM']
// Nota: mantiene case sensitivity

Casos de Uso Comunes​

  • Form inputs: Limpiar emails de formularios
  • Validación: Preparar emails para validación
  • Importación: Limpiar emails de archivos CSV/Excel
  • API requests: Sanitizar antes de enviar a servidor
  • Normalización: Normalizar emails de múltiples fuentes
  • Deduplicación: Limpiar antes de eliminar duplicados
  • Database storage: Sanitizar antes de guardar en BD

Comportamiento​

Email Válido​

Si el email (ya recortado) cumple Patterns.EMAIL:

  1. Elimina espacios al inicio y al final con .trim()
  2. Retorna el email sin más cambios
sanitizeEmail('  juan@example.com  ');
// 'juan@example.com'

sanitizeEmail('user.name+tag@example.co.uk');
// 'user.name+tag@example.co.uk'

Email Inválido​

Si el email NO cumple Patterns.EMAIL:

  1. Elimina espacios al inicio y al final con .trim()
  2. Remueve todo carácter que no coincida con [a-zA-Z0-9_/-@.]
  3. Retorna el resultado
sanitizeEmail('user name@example.com');
// 'username@example.com' (remueve el espacio)

sanitizeEmail('juan,perez@example.com');
// 'juanperez@example.com' (remueve la coma)

sanitizeEmail(' user#!@exa mple.com');
// 'user@example.com' (el email es inválido, así que también se remueven # y !)

Caracteres Permitidos​

Solo cuando el email NO cumple Patterns.EMAIL, se conservan estos caracteres:

  • Letras: a-z, A-Z
  • Números: 0-9
  • Guion bajo: _
  • El rango / a @ (códigos 0x2F a 0x40): / 0-9 : ; < = > ? @. En la expresión [^a-zA-Z0-9_/-@.] el fragmento /-@ es un rango, no los caracteres sueltos /, - y @.
  • Punto: .

Esto significa que el guion - y el + NO están en el conjunto: - queda fuera del rango (es 0x2D) y se elimina si el email no cumple el patrón.

sanitizeEmail('user name@example.com');   // 'username@example.com'
sanitizeEmail('user-na me@example.com'); // 'username@example.com' (el email era inválido: se pierde el guion)
sanitizeEmail('user-name@example.com'); // 'user-name@example.com' (válido: se retorna intacto)

Notas Técnicas​

  • Patterns.EMAIL: Importa Patterns desde @tiendana/utils (no existe el subpath @tiendana/utils/patterns). El patrón no tiene la bandera i, así que un email con mayúsculas no lo cumple y pasa por la rama de limpieza
  • Regex de limpieza: /[^a-zA-Z0-9_/-@.]/g
  • Trim: Usa .trim() para eliminar espacios
  • Case-sensitive: NO convierte a lowercase (preserva mayúsculas/minúsculas)
  • Inmutabilidad: No modifica el string original
  • Performance: O(n) donde n es la longitud del email

Limitaciones​

No convierte a lowercase

La función NO convierte el email a minúsculas, lo que puede causar problemas de deduplicación:

sanitizeEmail('JUAN@EXAMPLE.COM');
// 'JUAN@EXAMPLE.COM' (mantiene mayúsculas)

// Para normalizar completamente:
function normalizeEmail(email: string): string {
return sanitizeEmail(email).toLowerCase();
}

normalizeEmail('JUAN@EXAMPLE.COM');
// 'juan@example.com'
No valida dominio

La función NO valida que el dominio exista o sea válido, solo el formato:

sanitizeEmail('user@nonexistentdomain123456.com');
// 'user@nonexistentdomain123456.com' (válido en formato, pero dominio no existe)

// Para validación completa, necesitas verificar el dominio:
async function validateEmailDomain(email: string): Promise<boolean> {
const cleaned = sanitizeEmail(email);
const domain = cleaned.split('@')[1];

try {
const response = await fetch(`https://dns-api.com/check/${domain}`);
return response.ok;
} catch {
return false;
}
}
Comportamiento con emails muy inválidos

Si el email es muy inválido, el resultado puede ser inesperado:

sanitizeEmail('this is not an email');
// 'thisisnotanemail' (remueve espacios pero no hay @)

sanitizeEmail('@@@@');
// '@@@@' (las @ pertenecen al rango permitido, no se eliminan)

// Siempre valida el resultado:
const cleaned = sanitizeEmail(input);
if (!Patterns.EMAIL.test(cleaned)) {
throw new Error('Email inválido');
}

Ver También​

  • Patterns - Patrones de validación incluyendo EMAIL
  • hasValue - Validar que el email tenga valor
  • Strings - Funciones de manipulación de strings