UNPKG

@grod30/hacienda-js

Version:

Biblioteca TypeScript para facturación electrónica de Costa Rica (Hacienda)

125 lines (122 loc) 3.23 kB
// src/signature/index.ts import { SignedXml } from "xml-crypto"; import { readFileSync } from "fs"; async function signXml(xml, options) { if (!xml || typeof xml !== "string") { throw new Error("Invalid XML"); } if (!options || typeof options !== "object" || Array.isArray(options)) { throw new Error("Invalid options"); } const { certPath, certType } = options; if (!certType) { throw new Error("Certificate type is required"); } if (!certPath) { throw new Error("Certificate path is required"); } if (certType !== "p12" && certType !== "pem") { throw new Error("Invalid certificate type"); } try { const cert = readFileSync(certPath); const sig = new SignedXml(); sig.keyInfoProvider = { getKeyInfo: () => `<X509Data><X509Certificate>${cert.toString("base64")}</X509Certificate></X509Data>`, getKey: () => cert }; sig.addReference("", [ "http://www.w3.org/2000/09/xmldsig#enveloped-signature" ]); sig.signingKey = cert; sig.computeSignature(xml); return sig.getSignedXml(); } catch (error) { if (error instanceof Error) { if (error.message.includes("ENOENT")) { throw new Error("File not found"); } throw error; } throw new Error("Signing failed"); } } // src/api/index.ts import axios from "axios"; var HaciendaAPI = class { constructor(config) { this.config = config; } async getToken(username, password) { const response = await axios.post(`${this.config.apiUrl}/token`, { grant_type: "password", client_id: this.config.clientId, username, password }); this.token = response.data.access_token; return this.token; } validateToken(token) { const useToken = token || this.token; if (!useToken) { throw new Error("Token no proporcionado"); } return useToken; } async makeRequest(method, url, data, token) { const useToken = this.validateToken(token); try { const config = { headers: { "Authorization": `Bearer ${useToken}`, "Content-Type": "application/json" } }; const response = method === "post" ? await axios.post(url, data, config) : await axios.get(url, config); return response.data; } catch (error) { if (error instanceof Error) { throw error; } throw new Error("Error desconocido"); } } async sendDocument(documentXml, token) { const response = await this.makeRequest( "post", `${this.config.apiUrl}/recepcion`, { xml: documentXml }, token ); return { clave: response.clave, fecha: response.fecha, estado: response.estado, mensaje: response.mensaje }; } async checkStatus(clave, token) { const response = await this.makeRequest( "get", `${this.config.apiUrl}/recepcion/${clave}`, void 0, token ); return { clave: response.clave, fecha: response.fecha, estado: response.estado, mensaje: response.mensaje }; } }; // src/xml/index.ts var validateXml = (xml) => { return xml.includes("FacturaElectronica"); }; export { HaciendaAPI, signXml, validateXml };