UNPKG

ci-validation

Version:

🇺🇾 Complete TypeScript/JavaScript library for validating Uruguayan CI (Cédula de Identidad) with official algorithm and government service integration

471 lines • 21.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExternalCiService = void 0; const Casmu_1 = require("./Casmu"); const Farmashop_1 = __importDefault(require("./Farmashop")); const Forum_1 = require("./Forum"); const NewCiService_1 = require("./NewCiService"); const PuntosMas_1 = __importDefault(require("./PuntosMas")); const SanRoque_1 = require("./SanRoque"); const Sisi_1 = require("./Sisi"); const Smi_1 = require("./Smi"); const Tata_1 = __importDefault(require("./Tata")); class ExternalCiService { async check(document, options, att = 0) { return this.queryCiInfo(document); } async queryCiInfoRaw(ci) { const sisiService = new Sisi_1.SisiService(); const sanRoqueService = new SanRoque_1.SanRoqueService(); const forumService = new Forum_1.ForumService(); const smiService = new Smi_1.SmiService(); const casmuService = new Casmu_1.Casmu(); const newCiService = new NewCiService_1.NewCiService(); const requests = [ new PuntosMas_1.default(ci).getPoints(), new Farmashop_1.default(ci).getPoints(), new Tata_1.default(ci).getPoints(), sisiService.checkUser({ ci }), sanRoqueService.checkMember({ ci }), forumService.checkMember({ ci }), smiService.checkUser({ ci }), casmuService .isUserRegistered(ci) .then((isRegistered) => ({ isRegistered })) .catch((error) => ({ error: error.message })), ]; const responses = await Promise.allSettled(requests); const queryCi = await newCiService.queryCiInfo(ci); const extraInfo = { puntosMas: responses[0].status === "fulfilled" ? responses[0].value : null, farmashop: responses[1].status === "fulfilled" ? responses[1].value : null, tata: responses[2].status === "fulfilled" ? responses[2].value : null, sisi: responses[3].status === "fulfilled" ? responses[3].value : null, sanRoque: responses[4].status === "fulfilled" ? responses[4].value : null, forum: responses[5].status === "fulfilled" ? responses[5].value : null, smi: responses[6].status === "fulfilled" ? responses[6].value : null, casmu: responses[7].status === "fulfilled" ? responses[7].value : null, }; console.log("queryCi", queryCi); if (queryCi && queryCi.success && queryCi.data) { queryCi.data.persona = { info: { ...queryCi.data.persona, }, ...extraInfo, }; return queryCi; } return { success: true, data: { persona: { cedula: ci, ...extraInfo, }, }, }; } /** * Transforms the raw queryCiInfo response into a user-friendly format * @param ci - The CI number * @returns Promise with user-friendly formatted data */ async queryCiInfo(ci) { try { const rawResponse = await this.queryCiInfoRaw(ci); if (!rawResponse.success || !rawResponse.data) { return { success: false, cedula: ci, data: { persona: { summary: { totalServices: 0, availableServices: 0, totalPoints: 0, hasRegistrations: false, }, services: [], }, }, error: [rawResponse.error || "Failed to fetch data"].join(", "), errors: [rawResponse.error || "Failed to fetch data"], }; } const persona = rawResponse.data.persona; const services = []; const errors = []; let totalPoints = 0; let availableServices = 0; // Process PuntosMas if (persona.puntosMas) { if (persona.puntosMas.error) { services.push({ service: "PuntosMas", status: "error", message: persona.puntosMas.error, }); errors.push(`PuntosMas: ${persona.puntosMas.error}`); } else if (persona.puntosMas.Total !== undefined) { const points = persona.puntosMas.Total || 0; totalPoints += points; availableServices++; services.push({ service: "PuntosMas", status: points > 0 ? "available" : "registered", points: points, message: points > 0 ? `Tienes ${points} puntos disponibles` : "Registrado sin puntos", }); } } // Process Farmashop if (persona.farmashop) { if (persona.farmashop.statusCode === 200 && persona.farmashop.responseContent) { const content = persona.farmashop.responseContent; if (content.valid) { availableServices++; const contactOptions = content.options?.map((opt) => ({ type: opt.type === "email" ? "email" : "mobile", value: opt.value, masked: opt.value.includes("*"), })) || []; services.push({ service: "Farmashop", status: "registered", message: "Cuenta activa y verificada", contactOptions: contactOptions, }); } else { services.push({ service: "Farmashop", status: "needs_action", message: content.message?.replace(/<[^>]*>/g, "") || "Requiere acción", actionRequired: "Completar registro o verificar email", }); } } else { services.push({ service: "Farmashop", status: "error", message: "Error de conexión con el servicio", }); errors.push("Farmashop: Error de conexión"); } } // Process Tata if (persona.tata) { if (Array.isArray(persona.tata)) { // Active member with contact data availableServices++; const contactOptions = persona.tata.map((contact) => ({ type: contact.type === "EMAIL" ? "email" : "other", value: contact.contactData, masked: contact.contactData.includes("*"), })); services.push({ service: "Tata", status: "registered", message: "Miembro activo del programa", contactOptions: contactOptions, }); } else if (persona.tata.internalCode) { switch (persona.tata.internalCode) { case "MEMBER_NOT_EXISTS": services.push({ service: "Tata", status: "not_registered", message: "No estás registrado en el programa", }); break; case "PENDING_OLD_MEMBER": services.push({ service: "Tata", status: "needs_action", message: "Miembro del programa anterior, requiere migración", actionRequired: "Contactar para migrar cuenta", }); break; default: services.push({ service: "Tata", status: "error", message: persona.tata.message || "Estado desconocido", }); errors.push(`Tata: ${persona.tata.message}`); } } } // Process Sisi if (persona.sisi) { if (persona.sisi.success && persona.sisi.hasUser) { availableServices++; const userInfo = persona.sisi.userInfo; // Extract points if available const points = userInfo?.points || 0; if (points > 0) { totalPoints += points; } services.push({ service: "Sisi", status: userInfo?.status === "active" || persona.sisi.hasUser ? "available" : "registered", message: userInfo?.message || `Usuario encontrado en el sistema${points > 0 ? ` con ${points} puntos` : ""}`, }); } else if (persona.sisi.success && !persona.sisi.hasUser) { services.push({ service: "Sisi", status: "not_registered", message: "No estás registrado en el programa Sisi", }); } else { services.push({ service: "Sisi", status: "error", message: persona.sisi.error || "Error al consultar el servicio Sisi", }); errors.push(`Sisi: ${persona.sisi.error || "Error de conexión"}`); } } // Process SanRoque if (persona.sanRoque) { if (persona.sanRoque.success && persona.sanRoque.hasUser && persona.sanRoque.member) { availableServices++; const member = persona.sanRoque.member; const points = persona.sanRoque.points?.available || 0; if (points > 0) { totalPoints += points; } // Use firstName or fallback to a generic name const memberName = member.firstName || "Miembro"; services.push({ service: "San Roque", status: points > 0 ? "available" : "registered", points: points, message: `${memberName} - ${points > 0 ? `${points} puntos disponibles` : "Miembro registrado"}`, }); } else if (persona.sanRoque.success && !persona.sanRoque.hasUser) { services.push({ service: "San Roque", status: "not_registered", message: "No estás registrado en el programa San Roque", }); } else { services.push({ service: "San Roque", status: "error", message: persona.sanRoque.error || "Error al consultar el servicio San Roque", }); errors.push(`San Roque: ${persona.sanRoque.error || "Error de conexión"}`); } } // Process Forum if (persona.forum) { if (persona.forum.success && persona.forum.hasUser && persona.forum.member) { availableServices++; const member = persona.forum.member; const points = persona.forum.points?.available || 0; if (points > 0) { totalPoints += points; } services.push({ service: "Forum", status: points > 0 ? "available" : member.status === "no_points" ? "registered" : "available", points: points, message: `${points > 0 ? `${points} puntos disponibles` : "Miembro registrado sin puntos"}`, }); } else if (persona.forum.success && !persona.forum.hasUser) { services.push({ service: "Forum", status: "not_registered", message: "No estás registrado en el programa Forum", }); } else { services.push({ service: "Forum", status: "error", message: persona.forum.error || "Error al consultar el servicio Forum", }); errors.push(`Forum: ${persona.forum.error || "Error de conexión"}`); } } // Process SMI if (persona.smi) { if (persona.smi.success && persona.smi.hasUser && persona.smi.member) { availableServices++; const member = persona.smi.member; const userData = member.userData; // Extract contact options if userData is available const contactOptions = []; if (userData) { if (userData.perMail && userData.perMail !== "") { contactOptions.push({ type: "email", value: userData.perMail, masked: userData.perMail.includes("*"), }); } if (userData.domicTel && userData.domicTel !== "") { contactOptions.push({ type: "phone", value: userData.domicTel, masked: userData.domicTel.includes("*"), }); } } services.push({ service: "SMI", status: "registered", message: userData ? `Usuario registrado en SMI - ID: ${userData.perID}` : "Usuario registrado en SMI", contactOptions: contactOptions.length > 0 ? contactOptions : undefined, }); } else if (persona.smi.success && !persona.smi.hasUser) { services.push({ service: "SMI", status: "not_registered", message: persona.smi.error === "no_user" ? "No estás registrado en SMI" : persona.smi.error || "No estás registrado en SMI", }); } else { // Handle authentication errors more gracefully if (persona.smi.error && persona.smi.error.includes("autenticación")) { services.push({ service: "SMI", status: "needs_action", message: "SMI requiere autenticación adicional", actionRequired: "Iniciar sesión en SMI para verificar registro", }); } else { services.push({ service: "SMI", status: "error", message: persona.smi.error || "Error al consultar el servicio SMI", }); errors.push(`SMI: ${persona.smi.error || "Error de conexión"}`); } } } // Process Casmu if (persona.casmu) { if (persona.casmu.error) { services.push({ service: "Casmu", status: "error", message: persona.casmu.error, }); errors.push(`Casmu: ${persona.casmu.error}`); } else if (persona.casmu.isRegistered !== undefined) { if (persona.casmu.isRegistered) { availableServices++; services.push({ service: "Casmu", status: "registered", message: "Usuario registrado en Casmu", }); } else { services.push({ service: "Casmu", status: "not_registered", message: "No estás registrado en Casmu", }); } } } // Process ANV if (persona.anv) { if (persona.anv.error) { services.push({ service: "ANV", status: "error", message: persona.anv.error, }); errors.push(`ANV: ${persona.anv.error}`); } else if (persona.anv.success && persona.anv.data) { availableServices++; // Extraer información útil del response de ANV const anvData = persona.anv.data; let message = "Persona encontrada en ANV"; // Si hay información específica en los datos, agregarla al mensaje if (anvData.nombre || anvData.apellido) { message = `${anvData.nombre || ""} ${anvData.apellido || ""}`.trim(); } else if (anvData.nombreCompleto) { message = anvData.nombreCompleto; } services.push({ service: "ANV", status: "registered", message: message || "Persona encontrada en ANV", }); } else if (persona.anv.success === false) { services.push({ service: "ANV", status: "not_registered", message: "No se encontró información en ANV", }); } } return { success: true, cedula: ci, data: { persona: { ...persona.info, summary: { totalServices: services.length, availableServices: availableServices, totalPoints: totalPoints, hasRegistrations: services.some((s) => ["registered", "available"].includes(s.status)), }, services: services, }, }, error: errors.length > 0 ? errors.join(", ") : undefined, errors: errors.length > 0 ? errors : undefined, }; } catch (error) { console.error(error); return { success: false, cedula: ci, data: { persona: { summary: { totalServices: 0, availableServices: 0, totalPoints: 0, hasRegistrations: false, }, services: [], }, }, error: [error instanceof Error ? error.message : "Unknown error occurred"].join(", "), errors: [error instanceof Error ? error.message : "Unknown error occurred"], }; } } async isServiceAvailable() { return true; } } exports.ExternalCiService = ExternalCiService; //# sourceMappingURL=ExternalCiService.js.map