npm package: @jysperu/schema-correo
Description: Esquemas para correos electrónicos: Mongoose, JSON Schema y Joi
Author: JYS Perú
Latest version: 1.0.2

# @jysperu/schema-correo

[![npm version](https://badge.fury.io/js/@jysperu%2Fschema-correo.svg)](https://badge.fury.io/js/@jysperu%2Fschema-correo)
[![npm downloads](https://img.shields.io/npm/dm/@jysperu/schema-correo)](https://www.npmjs.com/package/@jysperu/schema-correo)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
[![MongoDB](https://img.shields.io/badge/MongoDB-47A248?logo=mongodb&logoColor=white)](https://www.mongodb.com/)
[![Joi](https://img.shields.io/badge/Joi-FF6B6B?logo=joi&logoColor=white)](https://joi.dev/)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@jysperu/schema-correo)](https://bundlephobia.com/package/@jysperu/schema-correo)

Esquemas para correos electrónicos con soporte para **Mongoose**, **JSON Schema** y **Joi**.

## 🚀 Características

- 📧 **Validación** de correos electrónicos
- 🌍 **Formato estándar** RFC 5322 completo
- 🔧 **Extracción** automática de usuario y dominio
- 🏷️ **Clasificaciones** del uso de correo (Trabajo, Personal, etc.)
- ✅ **Estados** de validación y verificación

## 📦 Instalación

```bash
npm install @jysperu/schema-correo
```

## ⚡ Inicio Rápido

```typescript
import { MongoSchemaCorreo, JsonSchemaCorreo, JoiSchemaCorreo, parseCorreo } from "@jysperu/schema-correo";
import { ICorreo, ClasificacionCorreo } from "@jysperu/schema-correo";

// Mongoose
const PersonaSchema = new Schema({
  correos: [MongoSchemaCorreo],
});

// Joi Validation
const { error, value } = JoiSchemaCorreo.validate({
  correo: "usuario@ejemplo.com",
  tipo: "Personal",
  valido: true,
});

// JSON Schema
const validate = ajv.compile(JsonSchemaCorreo);
const isValid = validate(correoData);

// Función utilitaria para parsear correos
const correoParseado = parseCorreo("usuario@dominio.com", { tipo: "Personal" });
// Resultado: { correo: "usuario@dominio.com", usuario: "usuario", dominio: "dominio.com", tipo: "Personal" }
```

## 📚 Esquemas Disponibles

### 1. 🍃 Mongoose Schema

```typescript
import { MongoSchemaCorreo, ICorreo } from "@jysperu/schema-correo";
import { Schema, model, Document } from "mongoose";

interface IPersona extends Document {
  nombres: string;
  correos: ICorreo[];
}

const PersonaSchema = new Schema<IPersona>({
  nombres: { type: String, required: true },
  correos: [MongoSchemaCorreo], // Array de correos
});

const PersonaModel = model<IPersona>("Persona", PersonaSchema);
```

### 2. 📋 JSON Schema

```typescript
import { JsonSchemaCorreo } from "@jysperu/schema-correo";
import Ajv from "ajv";

const ajv = new Ajv();
const validate = ajv.compile(JsonSchemaCorreo);

const correo = {
  correo: "usuario@ejemplo.com",
  tipo: "Personal",
  nombre: "Juan Pérez",
  valido: true,
};

const valid = validate(correo);
if (!valid) console.log(validate.errors);
```

### 3. ✅ Joi Schema

```typescript
import { JoiSchemaCorreo } from "@jysperu/schema-correo";

// Validación individual
const { error, value } = JoiSchemaCorreo.validate({
  correo: "usuario@dominio.com",
  tipo: "Personal",
  nombre: "Ana García",
  valido: true,
});

if (error) {
  error.details.forEach((err) => console.log(`❌ ${err.path}: ${err.message}`));
}

// Para arrays de correos
import Joi from "@jysperu/joi-spanish";

const personaSchema = Joi.object({
  nombres: Joi.string().required(),
  correos: Joi.array().items(JoiSchemaCorreo).default([]),
});
```

## 🛠️ Casos de Uso Avanzados

### Crear persona con múltiples correos

```typescript
import { MongoSchemaCorreo, ICorreo, ClasificacionCorreo } from "@jysperu/schema-correo";

const persona = new PersonaModel({
  nombres: "Ana García",
  correos: [
    {
      correo: "ana.garcia@empresa.com",
      tipo: ClasificacionCorreo.TRABAJO,
      nombre: "Ana García",
      usuario: "ana.garcia",
      dominio: "empresa.com",
      valido: true,
      verificado: true,
    },
    {
      correo: "ana.personal@gmail.com",
      tipo: ClasificacionCorreo.PERSONAL,
      nombre: "Ana García",
      usuario: "ana.personal",
      dominio: "gmail.com",
      valido: true,
    },
  ],
});

await persona.save();
```

### Operaciones con correos

```typescript
// Buscar correos verificados
const correosVerificados = persona.correos.filter((correo) => correo.verificado);

// Encontrar correos de trabajo
const correosDetrabajo = persona.correos.filter((correo) => correo.tipo === ClasificacionCorreo.TRABAJO);

// Agregar nuevo correo
persona.correos.push({
  correo: "ana.backup@hotmail.com",
  tipo: "Backup",
  usuario: "ana.backup",
  dominio: "hotmail.com",
  valido: true,
});

await persona.save();
```

### Usar la función parseCorreo

```typescript
import { parseCorreo } from "@jysperu/schema-correo";

// Uso básico - extrae automáticamente usuario y dominio
const correo1 = parseCorreo("usuario@ejemplo.com");
console.log(correo1);
// { correo: "usuario@ejemplo.com", usuario: "usuario", dominio: "ejemplo.com" }

// Con configuración adicional
const correo2 = parseCorreo("Ana.Garcia@empresa.com", {
  tipo: "Trabajo",
  nombre: "Ana García",
  valido: true
});
console.log(correo2);
// {
//   correo: "Ana.Garcia@empresa.com",
//   usuario: "ana.garcia",
//   dominio: "empresa.com",
//   tipo: "Trabajo",
//   nombre: "Ana García",
//   valido: true
// }

// Crear múltiples correos parseados
const correos = [
  "juan@personal.com",
  "maria@trabajo.es",
  "admin@sistema.org"
].map(email => parseCorreo(email, { valido: true }));

console.log(correos);
```

## 📊 Esquema de Datos

### ✅ Campo Obligatorio

| Campo   | Tipo     | Validación                    | Descripción                        |
| ------- | -------- | ------------------------------- | ---------------------------------- |
| `correo` | `String` | Required, trim, formato email   | Dirección de correo electrónico |

### ⚙️ Campos Opcionales

| Campo        | Tipo      | Validación/Enum         | Defecto    | Descripción                           |
| ------------ | --------- | ------------------------ | ---------- | ------------------------------------- |
| `tipo`       | `String`  | Min 1 char, personalizable | "Personal" | Clasificación (Trabajo/Personal)   |
| `nombre`     | `String`  | Max 100 chars            | -          | Nombre de la persona                  |
| `usuario`    | `String`  | Max 64 chars, lowercase  | -          | Parte antes del @ (usuario)           |
| `dominio`    | `String`  | Max 255 chars, lowercase | -          | Parte después del @ (dominio)        |
| `valido`     | `Boolean` | true/false               | false      | Formato de correo válido              |
| `verificado` | `Boolean` | true/false               | false      | Correo verificado por el usuario      |

### 🏷️ Clasificaciones Personales

```typescript
enum ClasificacionCorreo {
  TRABAJO = "Trabajo",   // 🏢 Correo laboral
  PERSONAL = "Personal", // 👤 Correo personal
}
```

## 💡 Ejemplos de Datos

### 📧 Correo Personal (Completo)

```typescript
const correoCompleto: ICorreo = {
  correo: "ana.garcia@gmail.com",
  tipo: "Personal",
  nombre: "Ana García",
  usuario: "ana.garcia",
  dominio: "gmail.com",
  valido: true,
  verificado: true,
};
```

### 🏢 Correo de Trabajo

```typescript
const correoTrabajo: ICorreo = {
  correo: "jperez@empresa.com.pe",
  tipo: "Trabajo",
  nombre: "Juan Pérez",
  usuario: "jperez",
  dominio: "empresa.com.pe",
  valido: true,
  verificado: false,
};
```

### 🔄 Correo Temporal

```typescript
const correoTemporal: ICorreo = {
  correo: "temp.user@10minutemail.com",
  tipo: "Temporal",
  nombre: "Usuario Temporal",
  usuario: "temp.user",
  dominio: "10minutemail.com",
  valido: true,
  verificado: false,
};
```

### 🏫 Correo Educativo

```typescript
const correoEducativo: ICorreo = {
  correo: "estudiante@universidad.edu",
  tipo: "Educativo",
  nombre: "Estudiante Universitario",
  usuario: "estudiante",
  dominio: "universidad.edu",
  valido: true,
  verificado: true,
};
```

## 🔧 Configuración del Esquema

```typescript
// Configuración Mongoose
{
  strict: false,        // Permite campos adicionales
  timestamps: true,     // createdAt, updatedAt automáticos
  _id: true             // Cada correo tiene su propio ID
}

// Configuración Joi
{
  stripUnknown: false,  // Mantiene campos extra
  allowUnknown: true,   // Permite propiedades no definidas
  convert: true,        // Conversión automática de tipos
  abortEarly: false     // Muestra todos los errores
}
```

## 📋 JSON Schema Standalone

El archivo `correo.schema.json` se genera automáticamente en cada build:

```bash
# Usar correo.schema.json directamente
curl -O https://gitlab.com/tiny.node/schema/correo/-/raw/main/dist/correo.schema.json

# Validar con cualquier validador JSON Schema
cat data.json | ajv validate -s correo.schema.json
```

## 🧪 Testing y Validación

```typescript
// Test básico con Joi
import { JoiSchemaCorreo } from "@jysperu/schema-correo";

const testCases = [
  { correo: "usuario@dominio.com", valid: true },
  { correo: "", valid: false }, // Vacío
  { correo: "correo-invalido", valid: false }, // Sin @
  { correo: "test@", valid: false }, // Sin dominio
];

testCases.forEach((test) => {
  const result = JoiSchemaCorreo.validate(test);
  console.log(`${test.correo}: ${result.error ? "❌" : "✅"}`);
});
```

## 📦 Build y Distribución

```bash
# Construir el proyecto
npm run build

# Genera automáticamente:
# └── dist/
#     ├── correo.es.js       # ESM
#     ├── correo.cjs.js      # CommonJS
#     ├── correo.umd.js      # UMD
#     ├── *.d.ts             # TypeScript definitions
#     └── correo.schema.json # JSON Schema
```

## 🔗 Enlaces y Recursos

- 📘 **Repositorio**: [GitLab - schema-correo](https://gitlab.com/tiny.node/schema/correo)
- 🐛 **Issues**: [Reportar problemas](https://gitlab.com/tiny.node/schema/correo/issues)
- 📦 **npm**: [@jysperu/schema-correo](https://www.npmjs.com/package/@jysperu/schema-correo)
- 📚 **Documentación Joi**: [@jysperu/joi-spanish](https://www.npmjs.com/package/@jysperu/joi-spanish)
- 🏢 **JYS Perú**: [www.jys.pe](https://www.jys.pe)

## 📄 Licencia

**MIT License** - Consulta el archivo [LICENSE](./LICENSE) para detalles completos.

```text
MIT License - Copyright (c) 2025 JYS Perú
```

---

Desarrollado con ❤️ por [**JYS Perú**](https://www.jys.pe)