@jysperu/schema-telefono
v1.0.1
Published
Esquemas para números telefónicos: Mongoose, JSON Schema y Joi
Downloads
215
Maintainers
Readme
@jysperu/schema-telefono
Esquemas para números telefónicos con soporte para Mongoose, JSON Schema y Joi.
🚀 Características
- 📞 Validación de números telefónicos
- 🌍 Soporte internacional completo (E.164, códigos de país)
- 🔧 Tipos de línea telefónica (MOBILE, FIXED_LINE, etc.)
- 🏷️ Clasificaciones del uso telefónico (Trabajo, Personal, etc.)
- ✅ Estados de validación y verificación
📦 Instalación
npm install @jysperu/schema-telefono⚡ Inicio Rápido
import { MongoSchemaTelefono, JsonSchemaTelefono, JoiSchemaTelefono } from "@jysperu/schema-telefono";
import { ITelefono, TipoLineaTelefonica, ClasificacionTelefono } from "@jysperu/schema-telefono";
// Mongoose
const PersonaSchema = new Schema({
telefonos: [MongoSchemaTelefono],
});
// Joi Validation
const { error, value } = JoiSchemaTelefono.validate({
telefono: "987654321",
countrycode: "pe", // → "PE" automáticamente
whatsapp: true,
});
// JSON Schema
const validate = ajv.compile(JsonSchemaTelefono);
const isValid = validate(telefonoData);📚 Esquemas Disponibles
1. 🍃 Mongoose Schema
import { MongoSchemaTelefono, ITelefono } from "@jysperu/schema-telefono";
import { Schema, model, Document } from "mongoose";
interface IPersona extends Document {
nombres: string;
telefonos: ITelefono[];
}
const PersonaSchema = new Schema<IPersona>({
nombres: { type: String, required: true },
telefonos: [MongoSchemaTelefono], // Array de teléfonos
});
const PersonaModel = model<IPersona>("Persona", PersonaSchema);2. 📋 JSON Schema
import { JsonSchemaTelefono } from "@jysperu/schema-telefono";
import Ajv from "ajv";
const ajv = new Ajv();
const validate = ajv.compile(JsonSchemaTelefono);
const telefono = {
telefono: "987654321",
tipo: "Personal",
countrycode: "PE",
whatsapp: true,
};
const valid = validate(telefono);
if (!valid) console.log(validate.errors);3. ✅ Joi Schema
import { JoiSchemaTelefono } from "@jysperu/schema-telefono";
// Validación individual
const { error, value } = JoiSchemaTelefono.validate({
telefono: "987654321",
tipo: "Personal",
countrycode: "pe", // Se convierte a "PE"
whatsapp: true,
});
if (error) {
error.details.forEach((err) => console.log(`❌ ${err.path}: ${err.message}`));
}
// Para arrays de teléfonos
import Joi from "@jysperu/joi-spanish";
const personaSchema = Joi.object({
nombres: Joi.string().required(),
telefonos: Joi.array().items(JoiSchemaTelefono).default([]),
});🛠️ Casos de Uso Avanzados
Crear persona con múltiples teléfonos
import { MongoSchemaTelefono, ITelefono, TipoLineaTelefonica } from "@jysperu/schema-telefono";
const persona = new PersonaModel({
nombres: "Ana García",
telefonos: [
{
telefono: "987654321",
tipo: "Personal",
countrycode: "PE",
type: TipoLineaTelefonica.MOBILE,
whatsapp: true,
valido: true,
},
{
telefono: "014567890",
tipo: "Trabajo",
countrycode: "PE",
type: TipoLineaTelefonica.FIXED_LINE,
whatsapp: false,
valido: true,
},
],
});
await persona.save();Operaciones con teléfonos
// Buscar números de WhatsApp
const whatsappNumbers = persona.telefonos.filter((tel) => tel.whatsapp);
// Encontrar móviles verificados
const mobilesVerificados = persona.telefonos.filter((tel) => tel.type === TipoLineaTelefonica.MOBILE && tel.verificado);
// Agregar nuevo teléfono
persona.telefonos.push({
telefono: "999888777",
tipo: "Emergencia",
type: TipoLineaTelefonica.MOBILE,
whatsapp: true,
valido: true,
});
await persona.save();📊 Esquema de Datos
✅ Campo Obligatorio
| Campo | Tipo | Validación | Descripción |
| ---------- | -------- | -------------------------------- | --------------------------- |
| telefono | String | Required, trim, contiene dígitos | Número telefónico principal |
⚙️ Campos Opcionales
| Campo | Tipo | Validación/Enum | Defecto | Descripción |
| --------------- | --------- | -------------------------- | --------- | -------------------------------- |
| tipo | String | Min 1 char, personalizable | "Trabajo" | Clasificación (Trabajo/Personal) |
| countrycode | String | ISO 2-3 chars, uppercase | - | Código país (PE, US, BR, etc.) |
| country | String | Max 100 chars | - | Nombre completo del país |
| countrydial | String | +?\\d{1,4} | - | Código marcado (+51, +1, +55) |
| e164 | String | +[1-9]\\d{1,14} | - | Formato E.164 internacional |
| international | String | Libre | - | Formato internacional legible |
| national | String | Libre | - | Formato nacional del país |
| uri | String | Inicia con "tel:" | - | URI telefónica RFC 3966 |
| type | Enum | TipoLineaTelefonica | "MOBILE" | Clasificación técnica de línea |
| whatsapp | Boolean | true/false | false | Compatible con WhatsApp |
| valido | Boolean | true/false | false | Número técnicamente válido |
| verificado | Boolean | true/false | false | Verificado por el usuario |
📱 Tipos de Línea Telefónica
enum TipoLineaTelefonica {
MOBILE = "MOBILE", // 📱 Teléfono móvil
FIXED_LINE = "FIXED_LINE", // 🏠 Línea fija
FIXED_LINE_OR_MOBILE = "FIXED_LINE_OR_MOBILE", // 🔄 Puede ser fijo o móvil
TOLL_FREE = "TOLL_FREE", // 🆓 Número gratuito
PREMIUM_RATE = "PREMIUM_RATE", // 💰 Tarifa premium
VOIP = "VOIP", // 🌐 Voz sobre IP
PERSONAL_NUMBER = "PERSONAL_NUMBER", // 👤 Número personal
SHARED_COST = "SHARED_COST", // 🤝 Costo compartido
PAGER = "PAGER", // 📟 Buscapersonas
UAN = "UAN", // 🔗 Acceso universal
VOICEMAIL = "VOICEMAIL", // 📧 Buzón de voz
UNKNOWN = "UNKNOWN", // ❓ Tipo desconocido
}🏷️ Clasificaciones Personales
enum ClasificacionTelefono {
TRABAJO = "Trabajo", // 🏢 Teléfono laboral
PERSONAL = "Personal", // 👤 Teléfono personal
}💡 Ejemplos de Datos
📱 Móvil Personal (Completo)
const telefonoCompleto: ITelefono = {
telefono: "987 654 321",
tipo: "Personal",
countrycode: "PE",
country: "Peru",
countrydial: "+51",
e164: "+51987654321",
international: "+51 987 654 321",
national: "987 654 321",
uri: "tel:+51-987-654-321",
type: TipoLineaTelefonica.MOBILE,
whatsapp: true,
valido: true,
verificado: true,
};🏢 Fijo de Trabajo
const telefonoTrabajo: ITelefono = {
telefono: "(01) 456-7890",
tipo: "Trabajo",
countrycode: "PE",
country: "Peru",
e164: "+5114567890",
international: "+51 1 456 7890",
national: "(01) 456-7890",
type: TipoLineaTelefonica.FIXED_LINE,
whatsapp: false,
valido: true,
};🆓 Línea Gratuita
const lineaGratuita: ITelefono = {
telefono: "800-123-4567",
tipo: "Soporte",
countrycode: "US",
country: "United States",
type: TipoLineaTelefonica.TOLL_FREE,
whatsapp: false,
valido: true,
};🌐 VOIP Internacional
const voipSkype: ITelefono = {
telefono: "echo123",
tipo: "Test VOIP",
type: TipoLineaTelefonica.VOIP,
whatsapp: false,
valido: true,
};🔧 Configuración del Esquema
// Configuración Mongoose
{
strict: false, // Permite campos adicionales
timestamps: true, // createdAt, updatedAt automáticos
_id: true // Cada teléfono 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 telefono.schema.json se genera automáticamente en cada build:
# Usar telefono.schema.json directamente
curl -O https://gitlab.com/tiny.node/schema/telefono/-/raw/main/dist/telefono.schema.json
# Validar con cualquier validador JSON Schema
cat data.json | ajv validate -s telefono.schema.json🧪 Testing y Validación
// Test básico con Joi
import { JoiSchemaTelefono } from "@jysperu/schema-telefono";
const testCases = [
{ telefono: "987654321", valid: true },
{ telefono: "", valid: false }, // Vacío
{ telefono: "abc", valid: false }, // Sin dígitos
{ countrycode: "pe", expected: "PE" }, // Conversion
];
testCases.forEach((test) => {
const result = JoiSchemaTelefono.validate(test);
console.log(`${test.telefono}: ${result.error ? "❌" : "✅"}`);
});📦 Build y Distribución
# Construir el proyecto
npm run build
# Genera automáticamente:
# └── dist/
# ├── telefono.es.js # ESM
# ├── telefono.cjs.js # CommonJS
# ├── telefono.umd.js # UMD
# ├── *.d.ts # TypeScript definitions
# └── telefono.schema.json # JSON Schema🔗 Enlaces y Recursos
- 📘 Repositorio: GitLab - schema-telefono
- 🐛 Issues: Reportar problemas
- 📦 npm: @jysperu/schema-telefono
- 📚 Documentación Joi: @jysperu/joi-spanish
- 🏢 JYS Perú: www.jys.pe
📄 Licencia
MIT License - Consulta el archivo LICENSE para detalles completos.
MIT License - Copyright (c) 2025 JYS PerúDesarrollado con ❤️ por JYS Perú
