@receeco/pos-agent
Version:
Receeco POS Integration Middleware Agent
327 lines (326 loc) • 12.4 kB
JavaScript
;
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