UNPKG

roku-pkg-cli

Version:

A comprehensive CLI tool for managing multiple Roku projects with automated device discovery, build integration, and package generation. Perfect for CI/CD pipelines with full automation support.

157 lines (156 loc) • 7.62 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.discoverCommand = discoverCommand; const inquirer_1 = __importDefault(require("inquirer")); const config_manager_1 = require("../lib/config-manager"); const roku_discovery_1 = require("../lib/roku-discovery"); const roku_api_1 = require("../lib/roku-api"); const chalk_1 = __importDefault(require("chalk")); const ora_1 = __importDefault(require("ora")); function discoverCommand(program) { program .command('discover') .description('Discover Roku devices on the network and optionally configure one') .option('--configure', 'Configure a discovered device immediately') .option('--first-device', 'Automatically use the first discovered device (requires --configure)') .option('--password <password>', 'Provide the developer password (avoids interactive prompt)') .action(async (options) => { // Validate flag combinations if (options.firstDevice && !options.configure) { console.log(chalk_1.default.red('\nError: --first-device can only be used with --configure\n')); return; } console.log(chalk_1.default.bold('\nšŸ“” Discovering Roku devices on the network...\n')); const spinner = (0, ora_1.default)('Scanning for Roku devices...').start(); try { const devices = await roku_discovery_1.RokuDiscovery.discoverDevices(); spinner.stop(); if (devices.length === 0) { console.log(chalk_1.default.yellow('No Roku devices found on the network.')); console.log(chalk_1.default.gray('\nTroubleshooting tips:')); console.log(chalk_1.default.gray('• Make sure your Roku device is connected to the same network')); console.log(chalk_1.default.gray('• Enable "Developer mode" on your Roku device')); console.log(chalk_1.default.gray('• Check that ECP (External Control Protocol) is enabled')); console.log(chalk_1.default.gray('• Try configuring the device manually with "roku-pkg device"\n')); return; } console.log(chalk_1.default.green(`āœ“ Found ${devices.length} Roku device${devices.length === 1 ? '' : 's'}:\n`)); // Display discovered devices devices.forEach((device, index) => { console.log(chalk_1.default.cyan(`${index + 1}. ${device.name}`)); console.log(chalk_1.default.gray(` IP: ${device.ip}`)); console.log(chalk_1.default.gray(` Model: ${device.modelName}`)); console.log(chalk_1.default.gray(` Serial: ${device.serialNumber}`)); if (device.softwareVersion) { console.log(chalk_1.default.gray(` Software: ${device.softwareVersion}`)); } console.log(); }); // If configure option is provided, allow user to select and configure a device if (options.configure) { await configureDiscoveredDevice(devices, options.firstDevice, options.password); } else { console.log(chalk_1.default.blue('Use "roku-pkg discover --configure" to set up one of these devices.')); console.log(chalk_1.default.blue('Or use "roku-pkg generate --discover" to select a device during package generation.\n')); } } catch (error) { spinner.fail('Discovery failed'); console.log(chalk_1.default.red(`Error: ${error.message}\n`)); } }); } async function configureDiscoveredDevice(devices, autoSelectFirst, providedPassword) { const configManager = new config_manager_1.ConfigManager(); let selectedDevice; // Auto-select first device if flag is provided if (autoSelectFirst) { selectedDevice = devices[0]; console.log(chalk_1.default.blue(`šŸ¤– Auto-selecting first device: ${selectedDevice.name} (${selectedDevice.ip})\n`)); } else { // Let user select a device interactively const response = await inquirer_1.default.prompt([ { type: 'list', name: 'selectedDevice', message: 'Select a device to configure:', choices: [ ...devices.map((device, index) => ({ name: `${device.name} (${device.ip}) - ${device.modelName}`, value: device })), { name: chalk_1.default.gray('Cancel'), value: null } ] } ]); selectedDevice = response.selectedDevice; if (!selectedDevice) { console.log(chalk_1.default.gray('\nConfiguration cancelled.\n')); return; } } // Test device connectivity first const spinner = (0, ora_1.default)(`Testing connection to ${selectedDevice.name}...`).start(); const isReachable = await roku_discovery_1.RokuDiscovery.testDevice(selectedDevice); if (!isReachable) { spinner.fail(`Cannot connect to ${selectedDevice.name}`); console.log(chalk_1.default.red('Device is not reachable. Please check network connectivity.\n')); return; } spinner.succeed(`Connected to ${selectedDevice.name}`); // Get developer password let password = providedPassword; if (!password) { const response = await inquirer_1.default.prompt([ { type: 'password', name: 'password', message: 'Enter the Roku developer password:', mask: '*', validate: (input) => input ? true : 'Password is required' } ]); password = response.password; } else { console.log(chalk_1.default.gray(`Using provided password for ${selectedDevice.name}`)); } // Ensure password is available at this point if (!password) { console.log(chalk_1.default.red('Password is required but not provided.\n')); return; } // Test authentication const authSpinner = (0, ora_1.default)('Testing authentication...').start(); try { const rokuApi = new roku_api_1.RokuAPI(selectedDevice.ip, password); const authSuccess = await rokuApi.testConnection(); if (!authSuccess) { authSpinner.fail('Authentication test failed'); console.log(chalk_1.default.red('Unable to authenticate with the device. Please check your password.\n')); return; } authSpinner.succeed('Authentication successful'); // Save device configuration const deviceConfig = { ip: selectedDevice.ip, password: password, name: selectedDevice.name, modelName: selectedDevice.modelName, serialNumber: selectedDevice.serialNumber, softwareVersion: selectedDevice.softwareVersion }; configManager.setRokuDevice(deviceConfig); console.log(chalk_1.default.green(`\nāœ“ Device "${selectedDevice.name}" configured successfully!\n`)); console.log(chalk_1.default.blue('You can now use "roku-pkg generate" to build and deploy packages to this device.\n')); } catch (error) { authSpinner.fail('Authentication failed'); console.log(chalk_1.default.red(`Error: ${error.message}\n`)); } }