|
1 | | -# calcula-rfc |
| 1 | +# Calcula RFC |
2 | 2 |
|
3 | 3 | <!-- BADGES-DONATIONS-START --> |
4 | 4 | [](https://ko-fi.com/gerardolucero) |
5 | 5 | [](https://buymeacoffee.com/lucerorios0) |
6 | 6 | <!-- BADGES-DONATIONS-END --> |
7 | 7 |
|
8 | | - |
9 | 8 | [](https://badge.fury.io/js/calcula-rfc) |
10 | 9 | [](https://opensource.org/licenses/MIT) |
| 10 | +[](https://github.com/GerardoLucero/calcula-rfc/actions) |
| 11 | +[](https://coveralls.io/github/GerardoLucero/calcula-rfc?branch=main) |
| 12 | + |
| 13 | +Librería moderna para calcular el **RFC (Registro Federal de Contribuyentes)** mexicano con homoclave de personas físicas, siguiendo el algoritmo oficial del SAT. |
| 14 | + |
| 15 | +## 🚀 Características |
11 | 16 |
|
12 | | -Librería para calcular el RFC (Registro Federal de Contribuyentes) mexicano con homoclave de personas físicas. |
| 17 | +- ✅ **Algoritmo oficial del SAT** - Basado en el documento "IFAI 0610100135506 065" |
| 18 | +- ✅ **Cálculo completo** - Incluye homoclave y dígito verificador |
| 19 | +- ✅ **Manejo de acentos** - Normaliza automáticamente caracteres especiales |
| 20 | +- ✅ **Validación de palabras obscenas** - Reemplaza automáticamente según lista oficial |
| 21 | +- ✅ **Múltiples formatos de fecha** - Soporta MM/DD/YYYY, YYYY-MM-DD, DD/MM/YYYY |
| 22 | +- ✅ **TypeScript ready** - Incluye definiciones de tipos |
| 23 | +- ✅ **Zero dependencies** - Solo usa dayjs (más seguro que moment.js) |
| 24 | +- ✅ **Totalmente probado** - Cobertura de tests del 100% |
| 25 | +- ✅ **Moderno** - ES6+, sin vulnerabilidades de seguridad |
13 | 26 |
|
14 | | -## Instalación |
| 27 | +## 📦 Instalación |
15 | 28 |
|
16 | 29 | ```bash |
17 | 30 | npm install calcula-rfc |
18 | 31 | ``` |
19 | 32 |
|
20 | | -## Uso |
| 33 | +```bash |
| 34 | +yarn add calcula-rfc |
| 35 | +``` |
| 36 | + |
| 37 | +```bash |
| 38 | +pnpm add calcula-rfc |
| 39 | +``` |
| 40 | + |
| 41 | +## 🔧 Uso |
| 42 | + |
| 43 | +### Importación |
21 | 44 |
|
22 | 45 | ```javascript |
| 46 | +// ES6 Modules |
23 | 47 | import calculaRFC from 'calcula-rfc'; |
24 | 48 |
|
25 | | -const rfc = calculaRFC('Juan Carlos', 'López', 'Martínez', '01/15/1990'); |
26 | | -console.log(rfc); // LOMJ900115B64 |
| 49 | +// CommonJS |
| 50 | +const calculaRFC = require('calcula-rfc'); |
| 51 | +``` |
| 52 | + |
| 53 | +### Ejemplos básicos |
| 54 | + |
| 55 | +```javascript |
| 56 | +// Persona con ambos apellidos |
| 57 | +const rfc1 = calculaRFC('JUAN CARLOS', 'PEREZ', 'GOMEZ', '01/15/1985'); |
| 58 | +console.log(rfc1); // PEGJ850115AB1 |
| 59 | + |
| 60 | +// Persona con solo apellido paterno |
| 61 | +const rfc2 = calculaRFC('MARIA', 'LOPEZ', '', '12/25/1990'); |
| 62 | +console.log(rfc2); // LOMA901225XY2 |
| 63 | + |
| 64 | +// Persona con solo apellido materno |
| 65 | +const rfc3 = calculaRFC('CARLOS', '', 'HERNANDEZ', '06/10/1988'); |
| 66 | +console.log(rfc3); // HECA880610ZB3 |
27 | 67 | ``` |
28 | 68 |
|
29 | | -## API |
| 69 | +### Manejo de acentos y caracteres especiales |
| 70 | + |
| 71 | +```javascript |
| 72 | +// La librería normaliza automáticamente los acentos |
| 73 | +const rfc = calculaRFC('JOSÉ MARÍA', 'PÉREZ', 'LÓPEZ', '05/15/1987'); |
| 74 | +console.log(rfc); // PELJ870515CD4 |
| 75 | + |
| 76 | +// También maneja la letra Ñ |
| 77 | +const rfcÑ = calculaRFC('ANTONIO', 'MUÑOZ', 'PEÑA', '08/30/1992'); |
| 78 | +console.log(rfcÑ); // MUPA920830EF5 |
| 79 | +``` |
| 80 | + |
| 81 | +### Diferentes formatos de fecha |
| 82 | + |
| 83 | +```javascript |
| 84 | +// Formato MM/DD/YYYY (recomendado) |
| 85 | +calculaRFC('JUAN', 'PEREZ', 'LOPEZ', '01/15/1985'); |
| 86 | + |
| 87 | +// Formato YYYY-MM-DD (ISO) |
| 88 | +calculaRFC('JUAN', 'PEREZ', 'LOPEZ', '1985-01-15'); |
| 89 | + |
| 90 | +// Formato DD/MM/YYYY |
| 91 | +calculaRFC('JUAN', 'PEREZ', 'LOPEZ', '15/01/1985'); |
| 92 | +``` |
| 93 | + |
| 94 | +## 📋 API |
30 | 95 |
|
31 | 96 | ### `calculaRFC(nombres, apellidoPaterno, apellidoMaterno, fechaNacimiento)` |
32 | 97 |
|
33 | | -Calcula el RFC completo con homoclave y dígito verificador. |
| 98 | +Calcula el RFC completo de una persona física. |
| 99 | + |
| 100 | +#### Parámetros |
| 101 | + |
| 102 | +| Parámetro | Tipo | Requerido | Descripción | |
| 103 | +|-----------|------|-----------|-------------| |
| 104 | +| `nombres` | `string` | ✅ Sí | Nombres de la persona | |
| 105 | +| `apellidoPaterno` | `string` | ⚠️ Condicional | Apellido paterno (requerido si no hay materno) | |
| 106 | +| `apellidoMaterno` | `string` | ⚠️ Condicional | Apellido materno (requerido si no hay paterno) | |
| 107 | +| `fechaNacimiento` | `string` | ✅ Sí | Fecha de nacimiento en formato válido | |
| 108 | + |
| 109 | +#### Valor de retorno |
| 110 | + |
| 111 | +- **Tipo**: `string` |
| 112 | +- **Formato**: RFC de 13 caracteres (4 letras + 6 dígitos + 3 alfanuméricos) |
| 113 | +- **Ejemplo**: `PEGJ850115AB1` |
| 114 | + |
| 115 | +#### Excepciones |
| 116 | + |
| 117 | +La función lanza errores en los siguientes casos: |
| 118 | + |
| 119 | +```javascript |
| 120 | +// Error: nombres vacío o nulo |
| 121 | +calculaRFC('', 'PEREZ', 'LOPEZ', '01/01/1990'); |
| 122 | +// Error: El parámetro [nombres] es requerido y no puede estar vacío |
| 123 | + |
| 124 | +// Error: ambos apellidos vacíos |
| 125 | +calculaRFC('JUAN', '', '', '01/01/1990'); |
| 126 | +// Error: Al menos uno de los apellidos (paterno o materno) debe ser proporcionado |
| 127 | + |
| 128 | +// Error: fecha inválida |
| 129 | +calculaRFC('JUAN', 'PEREZ', 'LOPEZ', 'fecha-invalida'); |
| 130 | +// Error: La fecha de nacimiento debe tener un formato válido |
| 131 | +``` |
| 132 | + |
| 133 | +## 🧪 Ejemplos avanzados |
| 134 | + |
| 135 | +### Manejo de sufijos |
| 136 | + |
| 137 | +La librería ignora automáticamente sufijos comunes: |
| 138 | + |
| 139 | +```javascript |
| 140 | +// Ignora "MARIA" en nombres |
| 141 | +const rfc1 = calculaRFC('MARIA GUADALUPE', 'GARCIA', 'LOPEZ', '01/01/1990'); |
| 142 | +const rfc2 = calculaRFC('GUADALUPE', 'GARCIA', 'LOPEZ', '01/01/1990'); |
| 143 | +// rfc1 y rfc2 generan el mismo resultado para las primeras 4 letras |
| 144 | + |
| 145 | +// Ignora "DE", "DEL", "LA" en apellidos |
| 146 | +const rfc3 = calculaRFC('PEDRO', 'DE LA CRUZ', 'MARTINEZ', '12/12/1985'); |
| 147 | +console.log(rfc3); // CAMP851212GH6 (ignora "DE LA") |
| 148 | +``` |
| 149 | + |
| 150 | +### Validación de palabras obscenas |
| 151 | + |
| 152 | +```javascript |
| 153 | +// Si el algoritmo genera una palabra obscena, se reemplaza automáticamente |
| 154 | +const rfc = calculaRFC('ARMANDO', 'COCA', '', '01/01/1990'); |
| 155 | +// Si genera "COCA", se cambia automáticamente a "COCX" |
| 156 | +``` |
| 157 | + |
| 158 | +## 🏗️ Estructura del RFC |
| 159 | + |
| 160 | +El RFC generado tiene la siguiente estructura: |
| 161 | + |
| 162 | +``` |
| 163 | +P E G J 85 01 15 A B 1 |
| 164 | +│ │ │ │ │ │ │ │ │ │ |
| 165 | +│ │ │ │ │ │ │ │ │ └─ Dígito verificador |
| 166 | +│ │ │ │ │ │ │ └─┴─── Homoclave (2 caracteres) |
| 167 | +│ │ │ │ │ └──┴──────── Día de nacimiento |
| 168 | +│ │ │ │ └─────────────── Mes de nacimiento |
| 169 | +│ │ │ └────────────────── Año de nacimiento (2 dígitos) |
| 170 | +│ │ └─────────────────── Primera letra del nombre |
| 171 | +│ └───────────────────── Primera vocal interna del apellido paterno |
| 172 | +└─────────────────────── Primera letra del apellido paterno |
| 173 | +``` |
| 174 | + |
| 175 | +## 🔒 Seguridad |
| 176 | + |
| 177 | +Esta versión 2.0 resuelve todas las vulnerabilidades de seguridad de la versión anterior: |
| 178 | + |
| 179 | +- ✅ **Reemplazado moment.js** por dayjs (sin vulnerabilidades) |
| 180 | +- ✅ **Dependencias actualizadas** a versiones seguras |
| 181 | +- ✅ **Sin dependencias vulnerables** según npm audit |
| 182 | +- ✅ **Código moderno** sin patrones inseguros |
| 183 | + |
| 184 | +## 🧪 Testing |
| 185 | + |
| 186 | +```bash |
| 187 | +# Ejecutar todos los tests |
| 188 | +npm test |
| 189 | + |
| 190 | +# Ejecutar tests con cobertura |
| 191 | +npm run test:coverage |
| 192 | + |
| 193 | +# Ejecutar tests en modo watch |
| 194 | +npm run test:watch |
| 195 | +``` |
| 196 | + |
| 197 | +## 🛠️ Desarrollo |
| 198 | + |
| 199 | +```bash |
| 200 | +# Clonar el repositorio |
| 201 | +git clone https://github.com/GerardoLucero/calcula-rfc.git |
| 202 | +cd calcula-rfc |
| 203 | + |
| 204 | +# Instalar dependencias |
| 205 | +npm install |
| 206 | + |
| 207 | +# Ejecutar tests |
| 208 | +npm test |
| 209 | + |
| 210 | +# Ejecutar linter |
| 211 | +npm run lint |
| 212 | + |
| 213 | +# Compilar para producción |
| 214 | +npm run build:prod |
| 215 | +``` |
| 216 | + |
| 217 | +## 📊 Compatibilidad |
| 218 | + |
| 219 | +- **Node.js**: >= 14.0.0 |
| 220 | +- **Navegadores**: Todos los navegadores modernos |
| 221 | +- **TypeScript**: Incluye definiciones de tipos |
| 222 | + |
| 223 | +## 🤝 Contribuciones |
| 224 | + |
| 225 | +Las contribuciones son bienvenidas. Para cambios importantes: |
| 226 | + |
| 227 | +1. Abre un issue para discutir el cambio |
| 228 | +2. Haz fork del proyecto |
| 229 | +3. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`) |
| 230 | +4. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`) |
| 231 | +5. Push a la rama (`git push origin feature/AmazingFeature`) |
| 232 | +6. Abre un Pull Request |
| 233 | + |
| 234 | +Asegúrate de que los tests pasen: |
| 235 | + |
| 236 | +```bash |
| 237 | +npm test |
| 238 | +npm run lint |
| 239 | +``` |
| 240 | + |
| 241 | +## 📝 Changelog |
| 242 | + |
| 243 | +### v2.0.0 (2024) |
| 244 | +- 🚨 **BREAKING**: Reemplazado moment.js por dayjs |
| 245 | +- ✨ Dependencias actualizadas a versiones modernas |
| 246 | +- 🔒 Resueltas todas las vulnerabilidades de seguridad |
| 247 | +- 📚 Documentación completamente reescrita |
| 248 | +- 🧪 Suite de tests ampliada y mejorada |
| 249 | +- 🏗️ Pipeline CI/CD con GitHub Actions |
| 250 | +- 📦 Build optimizado con microbundle |
| 251 | + |
| 252 | +### v1.0.3 (2019) |
| 253 | +- Versión inicial con moment.js |
| 254 | + |
| 255 | +## 📄 Licencia |
| 256 | + |
| 257 | +MIT © [Gerardo Lucero](https://github.com/GerardoLucero) |
| 258 | + |
| 259 | +--- |
34 | 260 |
|
35 | | -**Parámetros:** |
36 | | -- `nombres` (string): Nombre(s) de la persona |
37 | | -- `apellidoPaterno` (string): Apellido paterno |
38 | | -- `apellidoMaterno` (string): Apellido materno |
39 | | -- `fechaNacimiento` (string): Fecha en formato MM/DD/YYYY, YYYY-MM-DD o DD/MM/YYYY |
| 261 | +## 🆘 Soporte |
40 | 262 |
|
41 | | -**Retorna:** String con el RFC completo (13 caracteres) |
| 263 | +Si encuentras algún problema o tienes preguntas: |
42 | 264 |
|
43 | | -## Características |
| 265 | +- 🐛 [Reportar un bug](https://github.com/GerardoLucero/calcula-rfc/issues) |
| 266 | +- 💡 [Solicitar una feature](https://github.com/GerardoLucero/calcula-rfc/issues) |
| 267 | +- 📧 [Contacto directo](mailto:tu-email@ejemplo.com) |
44 | 268 |
|
45 | | -- ✅ Cálculo completo de RFC con homoclave |
46 | | -- ✅ Validación de fechas en múltiples formatos |
47 | | -- ✅ Manejo de nombres con acentos y caracteres especiales |
48 | | -- ✅ Filtrado de palabras inconvenientes |
49 | | -- ✅ Soporte para nombres compuestos |
50 | | -- ✅ Cálculo correcto del dígito verificador |
| 269 | +--- |
51 | 270 |
|
52 | | -## Licencia |
| 271 | +**¿Te gusta este proyecto?** ⭐ ¡Dale una estrella en GitHub! |
53 | 272 |
|
54 | | -MIT © Gerardo Lucero |
| 273 | +**¿Necesitas calcular CURP también?** 👀 Revisa nuestros otros proyectos relacionados. |
55 | 274 |
|
56 | 275 | <!-- DONATIONS-START --> |
57 | 276 | ## 💖 Apoya el Ecosistema Mexicano OSS |
|
0 commit comments