@jysperu/schema-telefono 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +372 -0
- package/dist/telefono.cjs.js +1 -0
- package/dist/telefono.d.ts +158 -0
- package/dist/telefono.d.ts.map +1 -0
- package/dist/telefono.esm.js +1 -0
- package/dist/telefono.schema.json +90 -0
- package/dist/telefono.umd.js +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 JYS Perú
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
# @jysperu/schema-telefono
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/@jysperu%2Fschema-telefono)
|
|
4
|
+
[](https://www.npmjs.com/package/@jysperu/schema-telefono)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
[](https://www.mongodb.com/)
|
|
9
|
+
[](https://joi.dev/)
|
|
10
|
+
[](https://bundlephobia.com/package/@jysperu/schema-telefono)
|
|
11
|
+
|
|
12
|
+
Esquemas para números telefónicos con soporte para **Mongoose**, **JSON Schema** y **Joi**.
|
|
13
|
+
|
|
14
|
+
## 🚀 Características
|
|
15
|
+
|
|
16
|
+
- 📞 **Validación** de números telefónicos
|
|
17
|
+
- 🌍 **Soporte internacional** completo (E.164, códigos de país)
|
|
18
|
+
- 🔧 **Tipos** de línea telefónica (MOBILE, FIXED_LINE, etc.)
|
|
19
|
+
- 🏷️ **Clasificaciones** del uso telefónico (Trabajo, Personal, etc.)
|
|
20
|
+
- ✅ **Estados** de validación y verificación
|
|
21
|
+
|
|
22
|
+
## 📦 Instalación
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @jysperu/schema-telefono
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## ⚡ Inicio Rápido
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { MongoSchemaTelefono, JsonSchemaTelefono, JoiSchemaTelefono } from "@jysperu/schema-telefono";
|
|
32
|
+
import { ITelefono, TipoLineaTelefonica, ClasificacionTelefono } from "@jysperu/schema-telefono";
|
|
33
|
+
|
|
34
|
+
// Mongoose
|
|
35
|
+
const PersonaSchema = new Schema({
|
|
36
|
+
telefonos: [MongoSchemaTelefono],
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Joi Validation
|
|
40
|
+
const { error, value } = JoiSchemaTelefono.validate({
|
|
41
|
+
telefono: "987654321",
|
|
42
|
+
countrycode: "pe", // → "PE" automáticamente
|
|
43
|
+
whatsapp: true,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// JSON Schema
|
|
47
|
+
const validate = ajv.compile(JsonSchemaTelefono);
|
|
48
|
+
const isValid = validate(telefonoData);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 📚 Esquemas Disponibles
|
|
52
|
+
|
|
53
|
+
### 1. 🍃 Mongoose Schema
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { MongoSchemaTelefono, ITelefono } from "@jysperu/schema-telefono";
|
|
57
|
+
import { Schema, model, Document } from "mongoose";
|
|
58
|
+
|
|
59
|
+
interface IPersona extends Document {
|
|
60
|
+
nombres: string;
|
|
61
|
+
telefonos: ITelefono[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const PersonaSchema = new Schema<IPersona>({
|
|
65
|
+
nombres: { type: String, required: true },
|
|
66
|
+
telefonos: [MongoSchemaTelefono], // Array de teléfonos
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const PersonaModel = model<IPersona>("Persona", PersonaSchema);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. 📋 JSON Schema
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { JsonSchemaTelefono } from "@jysperu/schema-telefono";
|
|
76
|
+
import Ajv from "ajv";
|
|
77
|
+
|
|
78
|
+
const ajv = new Ajv();
|
|
79
|
+
const validate = ajv.compile(JsonSchemaTelefono);
|
|
80
|
+
|
|
81
|
+
const telefono = {
|
|
82
|
+
telefono: "987654321",
|
|
83
|
+
tipo: "Personal",
|
|
84
|
+
countrycode: "PE",
|
|
85
|
+
whatsapp: true,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const valid = validate(telefono);
|
|
89
|
+
if (!valid) console.log(validate.errors);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3. ✅ Joi Schema
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { JoiSchemaTelefono } from "@jysperu/schema-telefono";
|
|
96
|
+
|
|
97
|
+
// Validación individual
|
|
98
|
+
const { error, value } = JoiSchemaTelefono.validate({
|
|
99
|
+
telefono: "987654321",
|
|
100
|
+
tipo: "Personal",
|
|
101
|
+
countrycode: "pe", // Se convierte a "PE"
|
|
102
|
+
whatsapp: true,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (error) {
|
|
106
|
+
error.details.forEach((err) => console.log(`❌ ${err.path}: ${err.message}`));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Para arrays de teléfonos
|
|
110
|
+
import Joi from "@jysperu/joi-spanish";
|
|
111
|
+
|
|
112
|
+
const personaSchema = Joi.object({
|
|
113
|
+
nombres: Joi.string().required(),
|
|
114
|
+
telefonos: Joi.array().items(JoiSchemaTelefono).default([]),
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 🛠️ Casos de Uso Avanzados
|
|
119
|
+
|
|
120
|
+
### Crear persona con múltiples teléfonos
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { MongoSchemaTelefono, ITelefono, TipoLineaTelefonica } from "@jysperu/schema-telefono";
|
|
124
|
+
|
|
125
|
+
const persona = new PersonaModel({
|
|
126
|
+
nombres: "Ana García",
|
|
127
|
+
telefonos: [
|
|
128
|
+
{
|
|
129
|
+
telefono: "987654321",
|
|
130
|
+
tipo: "Personal",
|
|
131
|
+
countrycode: "PE",
|
|
132
|
+
type: TipoLineaTelefonica.MOBILE,
|
|
133
|
+
whatsapp: true,
|
|
134
|
+
valido: true,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
telefono: "014567890",
|
|
138
|
+
tipo: "Trabajo",
|
|
139
|
+
countrycode: "PE",
|
|
140
|
+
type: TipoLineaTelefonica.FIXED_LINE,
|
|
141
|
+
whatsapp: false,
|
|
142
|
+
valido: true,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
await persona.save();
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Operaciones con teléfonos
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Buscar números de WhatsApp
|
|
154
|
+
const whatsappNumbers = persona.telefonos.filter((tel) => tel.whatsapp);
|
|
155
|
+
|
|
156
|
+
// Encontrar móviles verificados
|
|
157
|
+
const mobilesVerificados = persona.telefonos.filter((tel) => tel.type === TipoLineaTelefonica.MOBILE && tel.verificado);
|
|
158
|
+
|
|
159
|
+
// Agregar nuevo teléfono
|
|
160
|
+
persona.telefonos.push({
|
|
161
|
+
telefono: "999888777",
|
|
162
|
+
tipo: "Emergencia",
|
|
163
|
+
type: TipoLineaTelefonica.MOBILE,
|
|
164
|
+
whatsapp: true,
|
|
165
|
+
valido: true,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await persona.save();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## 📊 Esquema de Datos
|
|
172
|
+
|
|
173
|
+
### ✅ Campo Obligatorio
|
|
174
|
+
|
|
175
|
+
| Campo | Tipo | Validación | Descripción |
|
|
176
|
+
| ---------- | -------- | -------------------------------- | --------------------------- |
|
|
177
|
+
| `telefono` | `String` | Required, trim, contiene dígitos | Número telefónico principal |
|
|
178
|
+
|
|
179
|
+
### ⚙️ Campos Opcionales
|
|
180
|
+
|
|
181
|
+
| Campo | Tipo | Validación/Enum | Defecto | Descripción |
|
|
182
|
+
| --------------- | --------- | -------------------------- | --------- | -------------------------------- |
|
|
183
|
+
| `tipo` | `String` | Min 1 char, personalizable | "Trabajo" | Clasificación (Trabajo/Personal) |
|
|
184
|
+
| `countrycode` | `String` | ISO 2-3 chars, uppercase | - | Código país (PE, US, BR, etc.) |
|
|
185
|
+
| `country` | `String` | Max 100 chars | - | Nombre completo del país |
|
|
186
|
+
| `countrydial` | `String` | `+?\\d{1,4}` | - | Código marcado (+51, +1, +55) |
|
|
187
|
+
| `e164` | `String` | `+[1-9]\\d{1,14}` | - | Formato E.164 internacional |
|
|
188
|
+
| `international` | `String` | Libre | - | Formato internacional legible |
|
|
189
|
+
| `national` | `String` | Libre | - | Formato nacional del país |
|
|
190
|
+
| `uri` | `String` | Inicia con "tel:" | - | URI telefónica RFC 3966 |
|
|
191
|
+
| `type` | `Enum` | TipoLineaTelefonica | "MOBILE" | Clasificación técnica de línea |
|
|
192
|
+
| `whatsapp` | `Boolean` | true/false | false | Compatible con WhatsApp |
|
|
193
|
+
| `valido` | `Boolean` | true/false | false | Número técnicamente válido |
|
|
194
|
+
| `verificado` | `Boolean` | true/false | false | Verificado por el usuario |
|
|
195
|
+
|
|
196
|
+
### 📱 Tipos de Línea Telefónica
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
enum TipoLineaTelefonica {
|
|
200
|
+
MOBILE = "MOBILE", // 📱 Teléfono móvil
|
|
201
|
+
FIXED_LINE = "FIXED_LINE", // 🏠 Línea fija
|
|
202
|
+
FIXED_LINE_OR_MOBILE = "FIXED_LINE_OR_MOBILE", // 🔄 Puede ser fijo o móvil
|
|
203
|
+
TOLL_FREE = "TOLL_FREE", // 🆓 Número gratuito
|
|
204
|
+
PREMIUM_RATE = "PREMIUM_RATE", // 💰 Tarifa premium
|
|
205
|
+
VOIP = "VOIP", // 🌐 Voz sobre IP
|
|
206
|
+
PERSONAL_NUMBER = "PERSONAL_NUMBER", // 👤 Número personal
|
|
207
|
+
SHARED_COST = "SHARED_COST", // 🤝 Costo compartido
|
|
208
|
+
PAGER = "PAGER", // 📟 Buscapersonas
|
|
209
|
+
UAN = "UAN", // 🔗 Acceso universal
|
|
210
|
+
VOICEMAIL = "VOICEMAIL", // 📧 Buzón de voz
|
|
211
|
+
UNKNOWN = "UNKNOWN", // ❓ Tipo desconocido
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 🏷️ Clasificaciones Personales
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
enum ClasificacionTelefono {
|
|
219
|
+
TRABAJO = "Trabajo", // 🏢 Teléfono laboral
|
|
220
|
+
PERSONAL = "Personal", // 👤 Teléfono personal
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 💡 Ejemplos de Datos
|
|
225
|
+
|
|
226
|
+
### 📱 Móvil Personal (Completo)
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const telefonoCompleto: ITelefono = {
|
|
230
|
+
telefono: "987 654 321",
|
|
231
|
+
tipo: "Personal",
|
|
232
|
+
countrycode: "PE",
|
|
233
|
+
country: "Peru",
|
|
234
|
+
countrydial: "+51",
|
|
235
|
+
e164: "+51987654321",
|
|
236
|
+
international: "+51 987 654 321",
|
|
237
|
+
national: "987 654 321",
|
|
238
|
+
uri: "tel:+51-987-654-321",
|
|
239
|
+
type: TipoLineaTelefonica.MOBILE,
|
|
240
|
+
whatsapp: true,
|
|
241
|
+
valido: true,
|
|
242
|
+
verificado: true,
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 🏢 Fijo de Trabajo
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
const telefonoTrabajo: ITelefono = {
|
|
250
|
+
telefono: "(01) 456-7890",
|
|
251
|
+
tipo: "Trabajo",
|
|
252
|
+
countrycode: "PE",
|
|
253
|
+
country: "Peru",
|
|
254
|
+
e164: "+5114567890",
|
|
255
|
+
international: "+51 1 456 7890",
|
|
256
|
+
national: "(01) 456-7890",
|
|
257
|
+
type: TipoLineaTelefonica.FIXED_LINE,
|
|
258
|
+
whatsapp: false,
|
|
259
|
+
valido: true,
|
|
260
|
+
};
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 🆓 Línea Gratuita
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
const lineaGratuita: ITelefono = {
|
|
267
|
+
telefono: "800-123-4567",
|
|
268
|
+
tipo: "Soporte",
|
|
269
|
+
countrycode: "US",
|
|
270
|
+
country: "United States",
|
|
271
|
+
type: TipoLineaTelefonica.TOLL_FREE,
|
|
272
|
+
whatsapp: false,
|
|
273
|
+
valido: true,
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 🌐 VOIP Internacional
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const voipSkype: ITelefono = {
|
|
281
|
+
telefono: "echo123",
|
|
282
|
+
tipo: "Test VOIP",
|
|
283
|
+
type: TipoLineaTelefonica.VOIP,
|
|
284
|
+
whatsapp: false,
|
|
285
|
+
valido: true,
|
|
286
|
+
};
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## 🔧 Configuración del Esquema
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
// Configuración Mongoose
|
|
293
|
+
{
|
|
294
|
+
strict: false, // Permite campos adicionales
|
|
295
|
+
timestamps: true, // createdAt, updatedAt automáticos
|
|
296
|
+
_id: true // Cada teléfono tiene su propio ID
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Configuración Joi
|
|
300
|
+
{
|
|
301
|
+
stripUnknown: false, // Mantiene campos extra
|
|
302
|
+
allowUnknown: true, // Permite propiedades no definidas
|
|
303
|
+
convert: true, // Conversión automática de tipos
|
|
304
|
+
abortEarly: false // Muestra todos los errores
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 📋 JSON Schema Standalone
|
|
309
|
+
|
|
310
|
+
El archivo `telefono.schema.json` se genera automáticamente en cada build:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Usar telefono.schema.json directamente
|
|
314
|
+
curl -O https://gitlab.com/tiny.node/schema/telefono/-/raw/main/dist/telefono.schema.json
|
|
315
|
+
|
|
316
|
+
# Validar con cualquier validador JSON Schema
|
|
317
|
+
cat data.json | ajv validate -s telefono.schema.json
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## 🧪 Testing y Validación
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// Test básico con Joi
|
|
324
|
+
import { JoiSchemaTelefono } from "@jysperu/schema-telefono";
|
|
325
|
+
|
|
326
|
+
const testCases = [
|
|
327
|
+
{ telefono: "987654321", valid: true },
|
|
328
|
+
{ telefono: "", valid: false }, // Vacío
|
|
329
|
+
{ telefono: "abc", valid: false }, // Sin dígitos
|
|
330
|
+
{ countrycode: "pe", expected: "PE" }, // Conversion
|
|
331
|
+
];
|
|
332
|
+
|
|
333
|
+
testCases.forEach((test) => {
|
|
334
|
+
const result = JoiSchemaTelefono.validate(test);
|
|
335
|
+
console.log(`${test.telefono}: ${result.error ? "❌" : "✅"}`);
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## 📦 Build y Distribución
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Construir el proyecto
|
|
343
|
+
npm run build
|
|
344
|
+
|
|
345
|
+
# Genera automáticamente:
|
|
346
|
+
# └── dist/
|
|
347
|
+
# ├── telefono.es.js # ESM
|
|
348
|
+
# ├── telefono.cjs.js # CommonJS
|
|
349
|
+
# ├── telefono.umd.js # UMD
|
|
350
|
+
# ├── *.d.ts # TypeScript definitions
|
|
351
|
+
# └── telefono.schema.json # JSON Schema
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## 🔗 Enlaces y Recursos
|
|
355
|
+
|
|
356
|
+
- 📘 **Repositorio**: [GitLab - schema-telefono](https://gitlab.com/tiny.node/schema/telefono)
|
|
357
|
+
- 🐛 **Issues**: [Reportar problemas](https://gitlab.com/tiny.node/schema/telefono/issues)
|
|
358
|
+
- 📦 **npm**: [@jysperu/schema-telefono](https://www.npmjs.com/package/@jysperu/schema-telefono)
|
|
359
|
+
- 📚 **Documentación Joi**: [@jysperu/joi-spanish](https://www.npmjs.com/package/@jysperu/joi-spanish)
|
|
360
|
+
- 🏢 **JYS Perú**: [www.jys.pe](https://www.jys.pe)
|
|
361
|
+
|
|
362
|
+
## 📄 Licencia
|
|
363
|
+
|
|
364
|
+
**MIT License** - Consulta el archivo [LICENSE](./LICENSE) para detalles completos.
|
|
365
|
+
|
|
366
|
+
```text
|
|
367
|
+
MIT License - Copyright (c) 2025 JYS Perú
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
Desarrollado con ❤️ por [**JYS Perú**](https://www.jys.pe)
|