UNPKG

@receeco/pos-agent

Version:

Receeco POS Integration Middleware Agent

327 lines (326 loc) 12.4 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const promises_1 = __importDefault(require("fs/promises")); const path_1 = __importDefault(require("path")); const logger_1 = require("./utils/logger"); const axios_1 = __importDefault(require("axios")); const logger = (0, logger_1.createLogger)(); const program = new commander_1.Command(); program .name("receeco-pos") .description("Receeco POS Integration Agent CLI") .version("1.0.5"); program .command("init") .description("Initialize POS agent configuration") .option("--merchant-id <id>", "Merchant ID from Receeco dashboard") .option("--api-key <key>", "API key from Receeco dashboard") .option("--api-url <url>", "Receeco API URL", "https://receeco.com/api") .action(async (options) => { try { if (!options.merchantId) { console.error("Error: --merchant-id is required"); process.exit(1); } const config = { merchantId: options.merchantId, apiKey: options.apiKey || "", rececoApiUrl: options.apiUrl, rececoWebUrl: options.apiUrl.replace('/api', ''), enableOfflineMode: true, printQRCodes: true, port: 3001, logLevel: "info", }; const envContent = ` # Receeco POS Agent Configuration MERCHANT_ID=${config.merchantId} RECEECO_API_KEY=${config.apiKey} RECEECO_API_URL=${config.rececoApiUrl} RECEECO_WEB_URL=${config.rececoWebUrl} PORT=${config.port} LOG_LEVEL=${config.logLevel} NODE_ENV=production `.trim(); await promises_1.default.writeFile(".env", envContent); await promises_1.default.writeFile("config.json", JSON.stringify(config, null, 2)); console.log("✅ Receeco POS Agent initialized successfully!"); console.log("\nNext steps:"); console.log("1. Update .env file with your API keys"); console.log("2. Run: receeco-pos start"); console.log("3. Test integration: curl -X GET http://localhost:3001/health"); } catch (error) { console.error("❌ Initialization failed:", error); process.exit(1); } }); program .command("start") .description("Start the POS agent service") .option("--port <port>", "Port to run on", "3001") .option("--daemon", "Run as daemon service") .action(async (options) => { try { if (options.daemon) { console.log("Starting Receeco POS Agent as daemon..."); } else { console.log(`Starting Receeco POS Agent on port ${options.port}...`); process.env.PORT = options.port; require("./index"); } } catch (error) { console.error("❌ Failed to start service:", error); process.exit(1); } }); program .command("status") .description("Check POS agent status") .action(async () => { try { const axios = require("axios"); const port = process.env.PORT || 3001; const response = await axios.get(`http://localhost:${port}/health`); console.log("✅ POS Agent Status:", response.data); const queueResponse = await axios.get(`http://localhost:${port}/queue/status`); console.log("📋 Queue Status:", queueResponse.data); } catch (error) { console.error("❌ POS Agent is not running or unreachable"); console.error(" Make sure the service is started with: receeco-pos start"); } }); program .command("test") .description("Test POS integration with sample transaction") .option("--port <port>", "Port to test against", "3001") .action(async (options) => { try { const axios = require("axios"); const timestamp = Date.now(); const randomId = Math.random().toString(36).substring(2, 8); const uniqueMerchantId = process.env.MERCHANT_ID || `test-merchant-${randomId}`; const sampleTransaction = { merchantId: uniqueMerchantId, merchantName: `CLI Test Store ${randomId.toUpperCase()}`, merchantLogo: "https://res.cloudinary.com/dmmz1qe2d/image/upload/v1752945022/receeco_icon_at5wtn.png", accentColor: "#4a005c", items: [ { name: `Rice (5kg) - Test ${randomId}`, quantity: 1, unitPrice: 85.0 + Math.floor(Math.random() * 10), totalPrice: 85.0 + Math.floor(Math.random() * 10), sku: `RICE-CLI-${randomId}`, }, { name: `Bread - Test ${randomId}`, quantity: 2, unitPrice: 5.0, totalPrice: 10.0, sku: `BREAD-CLI-${randomId}`, }, ], totalAmount: 95.0 + Math.floor(Math.random() * 10), currency: "NGN", paymentMethod: "card", location: `CLI Test Store ${randomId.toUpperCase()} - Test Location`, timestamp: new Date().toISOString(), cashierId: "CLI001", terminalId: "TERMINAL001", testId: `cli-test-${timestamp}-${randomId}`, }; console.log("🧪 Testing POS integration..."); console.log("Sample transaction:", JSON.stringify(sampleTransaction, null, 2)); const response = await axios.post(`http://localhost:${options.port}/transactions`, sampleTransaction, { headers: { "Content-Type": "application/json" }, }); console.log("✅ Test successful!"); console.log("Response:", JSON.stringify(response.data, null, 2)); console.log("\n🎯 Test Results:"); console.log(`📱 Short Code: ${response.data.shortCode}`); console.log(`🔗 Receipt URL: ${response.data.receiptUrl}`); console.log(`\n💡 Next Steps:`); console.log(`1. Visit: https://receeco.com/app/scan`); console.log(`2. Enter short code: ${response.data.shortCode}`); console.log(`3. View your test receipt!`); } catch (error) { if (axios_1.default.isAxiosError(error)) { console.error("❌ Test failed:", error.response?.data || error.message); } else if (error instanceof Error) { console.error("❌ Test failed:", error.message); } else { console.error("❌ Test failed: An unknown error occurred", error); } } }); program .command("clear-queue") .description("Clear failed transactions from offline queue") .action(async () => { try { const { OfflineQueueService } = require("./services/offline-queue"); const queueService = new OfflineQueueService(); await queueService.clearFailedTransactions(); console.log("✅ Queue cleared successfully!"); const status = await queueService.getQueueStatus(); console.log("📋 Updated Queue Status:", { total: status.total, pending: status.pending, failed: status.failed }); process.exit(0); } catch (error) { console.error("❌ Failed to clear queue:", error); process.exit(1); } }); program .command("emulator") .description("Open POS emulator for visual testing") .action(async () => { try { const path = require("path"); const emulatorPath = path.join(__dirname, "..", "emulator.html"); console.log("🧪 Receeco POS Emulator"); console.log("📁 File location:", emulatorPath); console.log("🌐 Open this file in your web browser to test POS integration visually"); console.log(""); console.log("💡 Instructions:"); console.log("1. Make sure POS agent is running: receeco-pos start"); console.log("2. Open emulator.html in your browser"); console.log("3. Fill in transaction details and test"); const { exec } = require("child_process"); const platform = process.platform; if (platform === "win32") { exec(`start "" "${emulatorPath}"`); } else if (platform === "darwin") { exec(`open "${emulatorPath}"`); } else if (platform === "linux") { exec(`xdg-open "${emulatorPath}"`); } } catch (error) { console.error("❌ Failed to open emulator:", error); process.exit(1); } }); program .command("install-service") .description("Install as Windows service (Windows only)") .action(async () => { try { if (process.platform !== "win32") { console.error("❌ Service installation is only supported on Windows"); console.log("💡 For Linux/macOS, use pm2 or systemd"); process.exit(1); } const Service = require("node-windows").Service; const svc = new Service({ name: "Receeco POS Agent", description: "Receeco POS Integration Middleware Agent", script: path_1.default.join(__dirname, "index.js"), nodeOptions: ["--harmony", "--max_old_space_size=4096"], }); svc.on("install", () => { console.log("✅ Service installed successfully!"); console.log(" Service will start automatically"); console.log(""); console.log("📋 Service Management:"); console.log(" • Check status: services.msc (search 'Receeco POS Agent')"); console.log(" • Stop service: receeco-pos stop-service"); console.log(" • Start service: receeco-pos start-service"); console.log(" • Uninstall: receeco-pos uninstall-service"); svc.start(); }); svc.install(); } catch (error) { console.error("❌ Service installation failed:", error); process.exit(1); } }); program .command("uninstall-service") .description("Uninstall Windows service (Windows only)") .action(async () => { try { if (process.platform !== "win32") { console.error("❌ Service management is only supported on Windows"); process.exit(1); } const Service = require("node-windows").Service; const svc = new Service({ name: "Receeco POS Agent", script: path_1.default.join(__dirname, "index.js"), }); svc.on("uninstall", () => { console.log("✅ Service uninstalled successfully!"); }); svc.uninstall(); } catch (error) { console.error("❌ Service uninstall failed:", error); process.exit(1); } }); program .command("start-service") .description("Start Windows service (Windows only)") .action(async () => { try { if (process.platform !== "win32") { console.error("❌ Service management is only supported on Windows"); process.exit(1); } const Service = require("node-windows").Service; const svc = new Service({ name: "Receeco POS Agent", script: path_1.default.join(__dirname, "index.js"), }); svc.start(); console.log("✅ Service started successfully!"); } catch (error) { console.error("❌ Service start failed:", error); process.exit(1); } }); program .command("stop-service") .description("Stop Windows service (Windows only)") .action(async () => { try { if (process.platform !== "win32") { console.error("❌ Service management is only supported on Windows"); process.exit(1); } const Service = require("node-windows").Service; const svc = new Service({ name: "Receeco POS Agent", script: path_1.default.join(__dirname, "index.js"), }); svc.stop(); console.log("✅ Service stopped successfully!"); } catch (error) { console.error("❌ Service stop failed:", error); process.exit(1); } }); program.parse(); //# sourceMappingURL=cli.js.map