Librería TypeScript para generar PDFs de facturas SIAT con branding profesional, QR dinámico, múltiples estilos y marcas de agua automáticas
npm install siat-pdfbash
npm install siat-pdf
o
bun add siat-pdf
o
yarn add siat-pdf
`
🔧 Uso Básico
`typescript
import { PdfGenerator, DocumentStyle, PdfFormat } from 'siat-pdf';
// Configurar el generador
const pdfGenerator = new PdfGenerator();
// Datos SIAT
const siatData = {
urls: {
xml: 'https://example.com/invoice-001.xml',
pdf: 'https://example.com/invoice-001.pdf'
},
invoice: {
cabecera: {
codigoDocumentoSector: 1,
razonSocialEmisor: 'EMPRESA EJEMPLO S.A.',
nitEmisor: 12345678,
numeroFactura: 1001,
cuf: 'ABC123DEF456GHI789JKL',
fechaEmision: '2024-01-15T10:30:00',
nombreRazonSocial: 'CLIENTE EJEMPLO S.R.L.',
montoTotal: 175.00,
// ... más campos
},
detalle: [
{
codigoProducto: 12345,
descripcion: 'Producto de ejemplo',
cantidad: 2,
precioUnitario: 50.00,
subTotal: 100.00
}
]
},
metadata: {
cuf: 'ABC123DEF456GHI789JKL',
siatBranchCode: 1,
siatPointOfSaleCode: 1,
siatEnvironmentCode: 1, // 1 = Producción, 2 = Pruebas
siatModalityCode: 1,
siatDocumentSectorCode: 1,
siatActivityCode: 1,
siatNit: 12345678,
total: 175.00,
emissionCode: 1,
statusCode: 1, // 1 = Válido, 3 = Anulado
completedAt: '2024-01-15T10:30:00',
extraInfo: [
{ key: 'CustomField', value: 'Valor personalizado' },
{ key: 'Version', value: '1.0' }
]
}
};
// Generar PDF con estilo clásico
const pdfBuffer = await pdfGenerator.makeInvoiceDoc(
siatData,
'#1e40af', // Color
PdfFormat.LETTER, // Formato
DocumentStyle.CLASSIC, // Estilo
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==' // Logo en base64
);
// Generar rollo para impresora térmica
const rollPdf = await pdfGenerator.makeInvoiceRoll(siatData, PdfFormat.ROLL);
// Generar ticket minimalista
const ticketPdf = await pdfGenerator.makeInvoiceRoll(siatData, PdfFormat.TICKET);
`
📄 Formatos Disponibles
$3
- PdfFormat.LETTER - Carta estándar (8.5" x 11")
- PdfFormat.LEGAL - Legal (8.5" x 14")
- PdfFormat.HALF_LETTER - Media carta (5.5" x 8.5")
- PdfFormat.HALF_LEGAL - Media legal (5.5" x 7")
- PdfFormat.ROLL - Formato roll para impresoras térmicas
- PdfFormat.TICKET - Formato ticket ultra minimalista
$3
- DocumentStyle.CLASSIC - Diseño clásico con logo centrado
- DocumentStyle.MODERN - Diseño moderno con barra lateral
- DocumentStyle.MINIMALIST - Diseño elegante con líneas decorativas
- DocumentStyle.CORPORATE - Diseño premium con gradientes
🎨 Colores Personalizables
Puedes usar cualquier color en formato hexadecimal:
`typescript
// Ejemplos de colores
'#1e40af' // Azul
'#10b981' // Verde
'#f59e0b' // Naranja
'#dc2626' // Rojo
'#8b5cf6' // Púrpura
'#64748b' // Gris
`
🖼️ Logo Personalizado
Puedes incluir tu logo personalizado en formato base64:
`typescript
// Logo en base64 (PNG, JPG, etc.)
const logoBase64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
// Generar PDF con logo personalizado
const pdfBuffer = await pdfGenerator.makeInvoiceDoc(
siatData,
'#1e40af', // Color
PdfFormat.LETTER, // Formato
DocumentStyle.CLASSIC, // Estilo
logoBase64 // Logo en base64
);
// También puedes usar las opciones
const pdfBuffer2 = await pdfGenerator.makeInvoiceDoc(
siatData,
'#1e40af',
PdfFormat.LETTER,
DocumentStyle.CLASSIC,
undefined, // Sin logo directo
{ logo: logoBase64 } // Logo en opciones
);
`
Nota: Si no proporcionas un logo, se usará un logo por defecto transparente.
⚙️ Configuración
`typescript
interface IPdfGeneratorConfig {
defaultFormat: PdfFormat;
defaultStyle: DocumentStyle;
defaultColor: string;
embeddedFonts: boolean;
enableValidation: boolean;
enableLogging: boolean;
}
`
📋 Métodos Principales
$3
Genera un PDF completo con formato, estilo y logo personalizables.
$3
Genera un PDF en formato roll o ticket para impresoras térmicas.
- PdfFormat.ROLL - Formato roll estándar
- PdfFormat.TICKET - Formato ticket ultra minimalista
$3
Valida los datos SIAT y retorna errores específicos.
🔍 Validación de Datos
La librería incluye validación automática de datos SIAT:
`typescript
const validation = pdfGenerator.validateData(siatData);
if (validation.isValid) {
console.log('✅ Datos válidos');
} else {
console.log('❌ Errores:', validation.errors);
}
`
🏷️ Marcas de Agua Automáticas
La librería aplica automáticamente marcas de agua según el estado del documento:
- "SIN VALOR LEGAL": Cuando metadata.siatEnvironmentCode === 2 (ambiente de pruebas)
- "ANULADO": Cuando metadata.statusCode === 3 (documento anulado)
`typescript
// Documento de pruebas (marca de agua automática)
const pruebaData = {
...siatData,
metadata: {
...siatData.metadata,
siatEnvironmentCode: 2 // Marca "SIN VALOR LEGAL"
}
};
// Documento anulado (marca de agua automática)
const anuladoData = {
...siatData,
metadata: {
...siatData.metadata,
statusCode: 3 // Marca "ANULADO"
}
};
// Documento de pruebas y anulado (ambas marcas de agua)
const pruebasAnuladoData = {
...siatData,
metadata: {
...siatData.metadata,
siatEnvironmentCode: 2, // Marca "SIN VALOR LEGAL"
statusCode: 3 // Marca "ANULADO"
}
};
`
🏢 Branding y Autorización
Todos los documentos incluyen un mensaje de autorización profesional:
`
Generado con "FACTUGEST", sistema autorizado por Impuestos Nacionales. Soporte y contacto: 75434250
`
$3
- Fuente optimizada: Tamaño reducido para mejor presentación
- Elementos destacados: "FACTUGEST" y número de teléfono en negro puro
- Información completa: Sistema, autorización y contacto en una sola línea
- URL dinámica: QR code con URL específica por factura
$3
- URL: https://factugest.iathings.com/facturas?cuf={CUF}
- Enlace directo: https://factugest.iathings.com/facturas
- Soporte técnico: 75434250
📊 Estructura de Datos SIAT
`typescript
interface InvoiceResponse {
urls: {
xml: string;
pdf: string;
};
invoice: {
cabecera: {
codigoDocumentoSector?: number;
razonSocialEmisor?: string;
nitEmisor?: number;
numeroFactura?: number;
cuf?: string;
fechaEmision?: string;
nombreRazonSocial?: string;
montoTotal?: number;
// ... más campos
};
detalle: Array<{
codigoProducto?: number;
descripcion?: string;
cantidad?: number;
precioUnitario?: number;
subTotal?: number;
// ... más campos
}>;
};
metadata: {
cuf: string;
siatBranchCode: number;
siatPointOfSaleCode: number;
siatEnvironmentCode: number; // 1=Producción, 2=Pruebas
siatModalityCode: number;
siatDocumentSectorCode: number;
siatActivityCode: number;
siatNit: number;
total: number;
emissionCode: number;
statusCode: number; // 1=Válido, 3=Anulado
completedAt: string;
extraInfo?: Array<{
key: string;
value: string;
}>;
};
}
`
🛠️ Utilidades
$3
`typescript
import { DebugUtils } from 'siat-pdf';
// Crear resumen visual de datos
const summary = DebugUtils.createDataSummary(siatData);
console.log(summary);
// Logging con timestamp
DebugUtils.log('Mensaje de debug');
DebugUtils.logError('Error encontrado', error);
`
$3
`typescript
import { ValidationUtils } from 'siat-pdf';
ValidationUtils.isNotEmpty('texto'); // true
ValidationUtils.isPositiveNumber(100); // true
ValidationUtils.isValidEmail('test@test.com'); // true
ValidationUtils.isValidNIT('1234567890'); // true
`
$3
`typescript
import { FormatUtils } from 'siat-pdf';
FormatUtils.formatCurrency(1000); // "Bs 1.000,00"
FormatUtils.formatDate(new Date()); // "24 de agosto de 2025"
FormatUtils.truncateText('texto largo', 10); // "texto lar..."
`
🚀 Ejemplo Completo
`bash
Ejecutar el ejemplo incluido
bun run example.ts
`
El ejemplo genera múltiples PDFs con diferentes configuraciones y los guarda en la carpeta result/.
$3
`typescript
import { PdfGenerator, DocumentStyle, PdfFormat } from 'siat-pdf';
const pdfGenerator = new PdfGenerator();
// Generar diferentes estilos
const classicPdf = await pdfGenerator.makeInvoiceDoc(siatData, '#1e40af', PdfFormat.LETTER, DocumentStyle.CLASSIC);
const modernPdf = await pdfGenerator.makeInvoiceDoc(siatData, '#10b981', PdfFormat.LEGAL, DocumentStyle.MODERN);
const minimalistPdf = await pdfGenerator.makeInvoiceDoc(siatData, '#f59e0b', PdfFormat.HALF_LETTER, DocumentStyle.MINIMALIST);
const corporatePdf = await pdfGenerator.makeInvoiceDoc(siatData, '#8b5cf6', PdfFormat.HALF_LEGAL, DocumentStyle.CORPORATE);
// Generar rollos y tickets
const rollPdf = await pdfGenerator.makeInvoiceRoll(siatData, PdfFormat.ROLL);
const ticketPdf = await pdfGenerator.makeInvoiceRoll(siatData, PdfFormat.TICKET);
// Validar datos antes de generar
const validation = pdfGenerator.validateData(siatData);
if (validation.isValid) {
const pdf = await pdfGenerator.makeInvoiceDoc(siatData, '#1e40af', PdfFormat.LETTER, DocumentStyle.CLASSIC);
// Guardar PDF...
} else {
console.log('Errores de validación:', validation.errors);
}
`
📁 Estructura del Proyecto
`
src/
├── index.ts # Punto de entrada principal
├── pdf/ # Componentes de generación de PDF
│ ├── generator.ts # Clase principal PdfGenerator
│ ├── components.ts # Componentes de documentos
│ ├── builders.ts # Constructores de documentos
│ ├── config.ts # Configuración y constantes
│ └── utils.ts # Utilidades específicas
├── types/ # Definiciones de tipos
├── styles/ # Estilos y fuentes
└── utils/ # Utilidades generales
`
🔧 Desarrollo
`bash
Instalar dependencias
bun install
Compilar
bun run build
Ejecutar ejemplo
bun run example.ts
Ejecutar tests
bun test
`
📝 Licencia
MIT License - ver archivo LICENSE para más detalles.
🤝 Contribuir
1. Fork el proyecto
2. Crea una rama para tu feature (git checkout -b feature/AmazingFeature)
3. Commit tus cambios (git commit -m 'Add some AmazingFeature')
4. Push a la rama (git push origin feature/AmazingFeature`)