UNPKG

upn-with-qr-generator

Version:

A UPN + QR code generator for Slovenian banking system (2024 standard compliant) with environment-aware canvas support and isPNGGenerationAvailable method

168 lines (167 loc) 8.54 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UPNWriter = void 0; // src/UPNWriter.ts const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const UPNGenerator_1 = require("./UPNGenerator"); class UPNWriter { constructor(data) { this.canvasAvailable = false; this.upnGenerator = new UPNGenerator_1.UPNGenerator(data); this.initializeCanvas(); } initializeCanvas() { try { // Try to load canvas - this should work in regular Node.js environments const { createCanvas, loadImage, registerFont } = require('canvas'); this.canvas = { createCanvas, loadImage, registerFont }; this.canvasAvailable = true; // Register the Courier Bold font only when canvas is available try { // Use require.resolve to find the correct package location const packageRoot = path_1.default.dirname(require.resolve('upn-with-qr-generator/package.json')); const fontPath = path_1.default.join(packageRoot, 'assets', 'courbd.ttf'); registerFont(fontPath, { family: 'Courier Bold' }); } catch (fontError) { console.warn('Could not register Courier Bold font:', fontError instanceof Error ? fontError.message : String(fontError)); } } catch (error) { // Canvas not available (likely serverless environment or missing dependencies) console.warn('Canvas not available in this environment:', error instanceof Error ? error.message : String(error)); this.canvasAvailable = false; } } // Method to generate the UPN image on the canvas generateCanvas() { return __awaiter(this, void 0, void 0, function* () { if (!this.canvasAvailable) { throw new Error('PNG generation requires canvas library which is not available in this environment. ' + 'Use QR code generation only or run in a Node.js environment with canvas support.'); } // Use require.resolve to find the correct package location const packageRoot = path_1.default.dirname(require.resolve('upn-with-qr-generator/package.json')); const templatePath = path_1.default.join(packageRoot, 'assets', 'upn_sl.png'); const templateImage = yield this.canvas.loadImage(templatePath); const canvas = this.canvas.createCanvas(templateImage.width, templateImage.height); const context = canvas.getContext('2d'); context.drawImage(templateImage, 0, 0); const largeFontSize = '24px'; const smallFontSize = '20px'; context.fillStyle = '#000'; // Draw QR code with 10% increased size (242x242) const qrCodeBuffer = yield this.upnGenerator.generateQRCode(); context.drawImage(yield this.canvas.loadImage(qrCodeBuffer), 415, 42, 250, 250); const data = this.upnGenerator.getData(); // Large text fields context.font = `${largeFontSize} "Courier Bold"`; context.fillText(data.payerName || '', 697, 170); context.fillText(data.payerAddress || '', 697, 201); context.fillText(data.payerPost || '', 697, 233); context.fillText(data.receiverName || '', 418, 507); context.fillText(data.receiverAddress || '', 418, 538); context.fillText(data.receiverPost || '', 418, 570); context.fillText(data.receiverIban || '', 418, 400); // Handle receiver reference (new structure with fallback to legacy) const receiverRef = data.receiverReference || data.reference || ''; context.fillText(this.getReferencePrefix(receiverRef), 418, 451); context.fillText(this.getReferenceSuffix(receiverRef), 528, 451); context.fillText(data.purpose || '', 528, 340); context.fillText(data.code || '', 418, 340); context.fillText('***' + this.formatAmount(data.amount), 750, 285); // Handle payment date (new DD.MM.YYYY format vs legacy YYYYMMDD) const paymentDate = data.paymentDate || this.convertLegacyDate(data.dueDate); if (paymentDate) { context.fillText(paymentDate, 1155, 340); } // Small text fields context.font = `${smallFontSize} "Courier Bold"`; context.fillText(data.payerName || '', 30, 62); context.fillText(data.payerAddress || '', 30, 87); context.fillText(data.payerPost || '', 30, 112); context.fillText(data.receiverName || '', 30, 405); context.fillText(data.receiverAddress || '', 30, 430); context.fillText(data.receiverPost || '', 30, 455); context.fillText(data.receiverIban || '', 30, 300); context.fillText(receiverRef, 30, 351); context.fillText(data.purpose || '', 30, 165); if (paymentDate) { context.fillText(paymentDate, 30, 180); } return canvas; }); } // Save as PNG file saveAsPNG(outputPath) { return __awaiter(this, void 0, void 0, function* () { if (!this.canvasAvailable) { throw new Error('PNG generation requires canvas library which is not available in this environment. ' + 'Use QR code generation only or run in a Node.js environment with canvas support.'); } const canvas = yield this.generateCanvas(); const out = fs_1.default.createWriteStream(outputPath); const stream = canvas.createPNGStream(); stream.pipe(out); out.on('finish', () => console.log(`UPN image saved as ${outputPath}`)); }); } // Get PNG as a base64 string png() { return __awaiter(this, void 0, void 0, function* () { if (!this.canvasAvailable) { throw new Error('PNG generation requires canvas library which is not available in this environment. ' + 'Use QR code generation only or run in a Node.js environment with canvas support.'); } const canvas = yield this.generateCanvas(); return canvas.toDataURL('image/png').split(',')[1]; // Remove "data:image/png;base64," }); } // Get image buffer (equivalent to GD resource in PHP) gdResource() { return __awaiter(this, void 0, void 0, function* () { if (!this.canvasAvailable) { throw new Error('PNG generation requires canvas library which is not available in this environment. ' + 'Use QR code generation only or run in a Node.js environment with canvas support.'); } const canvas = yield this.generateCanvas(); return canvas.toBuffer('image/png'); }); } // Add method to check if PNG generation is available isPNGGenerationAvailable() { return this.canvasAvailable; } getReferencePrefix(reference) { return reference.slice(0, 4); } getReferenceSuffix(reference) { return reference.slice(4); } formatDate(date) { return `${date.slice(6, 8)}.${date.slice(4, 6)}.${date.slice(0, 4)}`; } formatAmount(amount) { return amount.toFixed(2); } convertLegacyDate(date) { if (!date || date.length !== 8) { return ''; } return `${date.slice(6, 8)}.${date.slice(4, 6)}.${date.slice(0, 4)}`; } } exports.UPNWriter = UPNWriter;