polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
592 lines (587 loc) • 28.5 kB
JavaScript
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractCommands = extractCommands;
exports.main = main;
exports.loadAndValidateConfig = loadAndValidateConfig;
exports.getVersion = getVersion;
const commander_1 = require("commander");
const fs_1 = require("fs");
const path_1 = require("path");
const errors_1 = require("./utils/errors");
const manager_1 = require("./config/manager");
const config_1 = require("./types/config");
const channel_commands_1 = require("./commands/channel.commands");
const stream_commands_1 = require("./commands/stream.commands");
const product_commands_1 = require("./commands/product.commands");
const monitor_commands_1 = require("./commands/monitor.commands");
const account_commands_1 = require("./commands/account.commands");
const use_commands_1 = require("./commands/use.commands");
const coupon_commands_1 = require("./commands/coupon.commands");
const setup_commands_1 = require("./commands/setup.commands");
const statistics_commands_1 = require("./commands/statistics.commands");
const statistics_commands_export_1 = require("./commands/statistics.commands.export");
const player_commands_1 = require("./commands/player.commands");
const playback_commands_1 = require("./commands/playback.commands");
const document_commands_1 = require("./commands/document.commands");
const session_commands_1 = require("./commands/session.commands");
const record_commands_1 = require("./commands/record.commands");
const chat_commands_1 = require("./commands/chat.commands");
const checkin_commands_1 = require("./commands/checkin.commands");
const qa_commands_1 = require("./commands/qa.commands");
const questionnaire_commands_1 = require("./commands/questionnaire.commands");
const lottery_commands_1 = require("./commands/lottery.commands");
const interaction_commands_1 = require("./commands/interaction.commands");
const donate_commands_1 = require("./commands/donate.commands");
const viewer_commands_1 = require("./commands/viewer.commands");
const watch_condition_commands_1 = require("./commands/watch-condition.commands");
const whitelist_commands_1 = require("./commands/whitelist.commands");
const platform_commands_1 = require("./commands/platform.commands");
const platform_label_commands_1 = require("./commands/platform-label.commands");
const promotion_commands_1 = require("./commands/promotion.commands");
const card_push_commands_1 = require("./commands/card-push.commands");
const transmit_commands_1 = require("./commands/transmit.commands");
const ai_commands_1 = require("./commands/ai.commands");
const global_commands_1 = require("./commands/global.commands");
const group_commands_1 = require("./commands/group.commands");
const finance_commands_1 = require("./commands/finance.commands");
const material_commands_1 = require("./commands/material.commands");
const webapp_commands_1 = require("./commands/webapp.commands");
const robot_commands_1 = require("./commands/robot.commands");
const partner_commands_1 = require("./commands/partner.commands");
const web_commands_1 = require("./commands/web.commands");
const invite_sales_commands_1 = require("./commands/invite-sales.commands");
const custom_field_commands_1 = require("./commands/custom-field.commands");
const user_commands_1 = require("./commands/user.commands");
process.on('uncaughtException', errors_1.handleUncaughtError);
process.on('unhandledRejection', errors_1.handleUnhandledRejection);
function getVersion() {
try {
const packagePath = (0, path_1.join)(__dirname, '..', 'package.json');
const packageJson = JSON.parse((0, fs_1.readFileSync)(packagePath, 'utf8'));
return packageJson.version;
}
catch (error) {
console.error('Failed to read version from package.json');
return '1.0.0';
}
}
async function loadAndValidateConfig(program) {
try {
const options = program.opts();
const configResult = await manager_1.configManager.load({
cliOptions: options,
});
if (configResult.config.debug) {
console.log('Configuration loaded successfully');
console.log(`Environment: ${configResult.config.environment}`);
console.log(`Base URL: ${configResult.config.baseUrl}`);
console.log(`Timeout: ${configResult.config.timeout}ms`);
console.log(`Max Retries: ${configResult.config.maxRetries}`);
console.log(`Loaded .env files: ${configResult.loadedEnvFiles.length}`);
if (configResult.loadedEnvFiles.length > 0) {
configResult.loadedEnvFiles.forEach(file => console.log(` - ${file}`));
}
}
return configResult.config;
}
catch (error) {
const args = process.argv.slice(2);
const isHelpOrVersion = args.some(arg => arg === '--help' || arg === '-h' || arg === '--version' || arg === '-v');
if (isHelpOrVersion) {
return null;
}
throw error;
}
}
function showQuickHelp() {
console.log(`Usage: polyv-live-cli [options] [command]
CLI tool for managing PolyV live streaming services
Commands:
account Manage account configurations
use Switch session account
channel Manage live channels
stream Stream operations
product Manage channel products
coupon Manage coupons
setup Initialize a scene with predefined resources
monitor Live monitoring dashboard
statistics View live streaming statistics data
global Manage global account settings
group Manage group account resources
finance Manage finance, billing, and moderation APIs
material Manage material library
webapp Manage WebApp roles and permissions
robot Manage global robots
partner Manage partner account tools
web Manage watch page configuration
invite-sales Manage user invite sales
custom-field Manage user custom fields
user Manage user account settings
interaction Manage cross-cutting live interaction APIs
Quick Start:
$ polyv-live-cli account add <name> --app-id <id> --app-secret <secret> # Add account
$ polyv-live-cli use <name> # Switch to account
$ polyv-live-cli channel list -a <name> # Use specific account (short)
$ polyv-live-cli channel --help # Channel operations
$ polyv-live-cli stream --help # Stream operations
$ polyv-live-cli setup e-commerce # Initialize e-commerce scene
Run 'polyv-live-cli --help' for full help or 'polyv-live-cli <command> --help' for command help.`);
}
async function main() {
const program = new commander_1.Command();
program
.name('polyv-live-cli')
.description('CLI tool for managing PolyV live streaming services')
.version(getVersion(), '-v, --version', 'display version number')
.helpOption('-h, --help', 'display help for command');
program.configureHelp({
helpWidth: 80,
sortSubcommands: true,
});
program
.option('--appId <id>', 'PolyV application ID')
.option('--appSecret <secret>', 'PolyV application secret')
.option('--userId <id>', 'PolyV user ID (optional)')
.option('-a, --account <name>', 'use specific account configuration')
.option('--verbose', 'show authentication source information');
program
.option(`--${config_1.CONFIG_CLI_OPTIONS.ENVIRONMENT} <env>`, 'environment (development|production|test)')
.option(`--${config_1.CONFIG_CLI_OPTIONS.DEBUG}`, 'enable debug mode')
.option(`--${config_1.CONFIG_CLI_OPTIONS.TIMEOUT} <ms>`, 'API timeout in milliseconds')
.option(`--${config_1.CONFIG_CLI_OPTIONS.BASE_URL} <url>`, 'API base URL')
.option(`--${config_1.CONFIG_CLI_OPTIONS.MAX_RETRIES} <num>`, 'maximum retry attempts')
.option(`--${config_1.CONFIG_CLI_OPTIONS.CONFIG_PATH} <path>`, 'custom configuration file path');
(0, account_commands_1.registerAccountCommands)(program);
(0, use_commands_1.registerUseCommand)(program);
(0, channel_commands_1.registerChannelCommands)(program);
(0, stream_commands_1.registerStreamCommands)(program);
(0, product_commands_1.registerProductCommands)(program);
(0, monitor_commands_1.registerMonitorCommands)(program);
(0, coupon_commands_1.registerCouponCommands)(program);
(0, setup_commands_1.registerSetupCommand)(program);
(0, statistics_commands_1.registerStatisticsCommands)(program);
(0, statistics_commands_export_1.registerStatisticsExportCommands)(program);
(0, player_commands_1.registerPlayerCommands)(program);
(0, playback_commands_1.registerPlaybackCommands)(program);
(0, document_commands_1.registerDocumentCommands)(program);
(0, session_commands_1.registerSessionCommands)(program);
(0, record_commands_1.registerRecordCommands)(program);
(0, chat_commands_1.registerChatCommands)(program);
(0, checkin_commands_1.registerCheckinCommands)(program);
(0, qa_commands_1.registerQaCommands)(program);
(0, questionnaire_commands_1.registerQuestionnaireCommands)(program);
(0, lottery_commands_1.registerLotteryCommands)(program);
(0, interaction_commands_1.registerInteractionCommands)(program);
(0, donate_commands_1.registerDonateCommands)(program);
(0, viewer_commands_1.registerViewerCommands)(program);
(0, watch_condition_commands_1.registerWatchConditionCommands)(program);
(0, whitelist_commands_1.registerWhitelistCommands)(program);
(0, platform_commands_1.registerPlatformCommands)(program);
(0, platform_label_commands_1.registerPlatformLabelCommands)(program);
(0, promotion_commands_1.registerPromotionCommands)(program);
(0, card_push_commands_1.registerCardPushCommands)(program);
(0, transmit_commands_1.registerTransmitCommands)(program);
(0, ai_commands_1.registerAiCommands)(program);
(0, global_commands_1.registerGlobalCommands)(program);
(0, group_commands_1.registerGroupCommands)(program);
(0, finance_commands_1.registerFinanceCommands)(program);
(0, material_commands_1.registerMaterialCommands)(program);
(0, webapp_commands_1.registerWebAppCommands)(program);
(0, robot_commands_1.registerRobotCommands)(program);
(0, partner_commands_1.registerPartnerCommands)(program);
(0, web_commands_1.registerWebCommands)(program);
(0, invite_sales_commands_1.registerInviteSalesCommands)(program);
(0, custom_field_commands_1.registerCustomFieldCommands)(program);
(0, user_commands_1.registerUserCommands)(program);
function getAllRegisteredCommands() {
const topLevel = [];
const subCommands = new Map();
if (program.commands && Array.isArray(program.commands)) {
program.commands.forEach(cmd => {
topLevel.push(cmd.name());
if (cmd.commands && cmd.commands.length > 0) {
const subCmdNames = cmd.commands.map((subcmd) => subcmd.name());
subCommands.set(cmd.name(), subCmdNames);
}
});
}
return { topLevel, subCommands };
}
function getCommandPathIndices(commandArgs) {
const indices = new Set();
let current = program;
let optionValueExpected = false;
for (let index = 0; index < commandArgs.length; index++) {
const arg = commandArgs[index];
if (!arg)
continue;
if (optionValueExpected) {
optionValueExpected = false;
continue;
}
if (arg.startsWith('-')) {
if (optionExpectsValue(current, arg) && commandArgs[index + 1]) {
optionValueExpected = true;
}
continue;
}
const next = findChildCommand(current, arg);
if (!next) {
break;
}
indices.add(index);
current = next;
}
return indices;
}
function isOptionValue(commandArgs, index) {
let current = program;
for (let cursor = 0; cursor < index; cursor++) {
const arg = commandArgs[cursor];
if (!arg)
continue;
if (arg.startsWith('-')) {
if (optionExpectsValue(current, arg)) {
if (cursor + 1 === index) {
return true;
}
cursor++;
}
continue;
}
const next = findChildCommand(current, arg);
if (next) {
current = next;
}
}
return false;
}
function findChildCommand(parent, name) {
const children = Array.isArray(parent.commands) ? parent.commands : [];
return children.find((cmd) => {
const aliases = typeof cmd.aliases === 'function' ? cmd.aliases() : [];
return cmd.name() === name || aliases.includes(name);
});
}
function optionExpectsValue(command, rawOption) {
const optionName = rawOption.includes('=') ? rawOption.slice(0, rawOption.indexOf('=')) : rawOption;
const options = Array.isArray(command.options) ? command.options : [];
const option = options.find((candidate) => candidate.long === optionName || candidate.short === optionName);
return !!option && (option.required || option.optional) && !rawOption.includes('=');
}
program.addHelpText('after', `
Quick Start:
$ polyv-live-cli account add <name> --app-id <id> --app-secret <secret> # Add account
$ polyv-live-cli use <name> # Switch to account
$ polyv-live-cli channel --help # Channel operations
$ polyv-live-cli stream --help # Stream operations
$ polyv-live-cli product --help # Product operations
$ polyv-live-cli coupon --help # Coupon operations
$ polyv-live-cli setup --list # List available scenes
$ polyv-live-cli monitor --help # Live monitoring dashboard
$ polyv-live-cli global --help # Global settings
$ polyv-live-cli group --help # Group account resources
$ polyv-live-cli finance --help # Finance and moderation
$ polyv-live-cli web --help # Watch page configuration
$ polyv-live-cli interaction --help # Cross-cutting live interaction APIs
Authentication:
- Use 'polyv-live-cli account add' to add accounts
- Use 'polyv-live-cli use <name>' to switch accounts
- Or use -a <name> or --account <name> to specify account for single command
- Or use --appId and --appSecret parameters
- Or set POLYV_APP_ID and POLYV_APP_SECRET environment variables
`);
let unknownCommand = null;
program.on('command:*', (args) => {
unknownCommand = args[0] || null;
});
program.exitOverride();
const args = process.argv.slice(2);
const isHelpOrVersion = args.some(arg => arg === '--help' || arg === '-h' || arg === '--version' || arg === '-v');
if (args.length === 0) {
showQuickHelp();
return;
}
const hasValidCommand = args.includes('channel') || args.includes('stream') || args.includes('product') || args.includes('coupon') || args.includes('setup') || args.includes('monitor') || args.includes('account') || args.includes('use') || args.includes('statistics') || args.includes('player') || args.includes('playback') || args.includes('document') || args.includes('session') || args.includes('record') || args.includes('chat') || args.includes('checkin') || args.includes('qa') || args.includes('questionnaire') || args.includes('lottery') || args.includes('donate') || args.includes('viewer') || args.includes('watch-condition') || args.includes('whitelist') || args.includes('platform') || args.includes('promotion') || args.includes('card-push') || args.includes('transmit') || args.includes('ai') || args.includes('global') || args.includes('group') || args.includes('finance') || args.includes('material') || args.includes('webapp') || args.includes('robot') || args.includes('partner') || args.includes('web');
if (hasValidCommand) {
try {
program.parse();
return;
}
catch (err) {
if (err.code === 'commander.help' || err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {
process.exit(0);
}
if (err.code && err.code.startsWith('commander.')) {
if (err.message && err.message !== '(outputHelp)') {
console.error(err.message);
}
process.exit(err.exitCode || 1);
}
throw err;
}
}
if (!isHelpOrVersion && args.length > 0) {
const hasGlobalOptions = args.some(arg => arg.startsWith('--appId') || arg.startsWith('--appSecret') || arg.startsWith('--userId') ||
arg.startsWith('--environment') || arg.startsWith('--debug') || arg.startsWith('--timeout') ||
arg.startsWith('--baseUrl') || arg.startsWith('--maxRetries') || arg.startsWith('--config'));
const hasCommands = args.some(arg => arg === 'channel' || arg === 'stream' || arg === 'product' || arg === 'coupon' || arg === 'setup' || arg === 'monitor' || arg === 'account' || arg === 'use' || arg === 'statistics' || arg === 'player' || arg === 'playback' || arg === 'document' || arg === 'session' || arg === 'checkin' || arg === 'help' || arg === 'watch-condition' || arg === 'whitelist' || arg === 'transmit' || arg === 'global' || arg === 'group' || arg === 'finance' || arg === 'material' || arg === 'webapp' || arg === 'robot' || arg === 'partner' || arg === 'web');
const hasPotentialCommands = args.some(arg => {
if (arg.startsWith('-'))
return false;
const argIndex = args.indexOf(arg);
if (argIndex === 0)
return true;
const prevArg = args[argIndex - 1];
if (!prevArg)
return true;
return !['--appId', '--appSecret', '--userId', '--environment', '--timeout', '--baseUrl', '--maxRetries', '--config'].includes(prevArg);
});
if (hasGlobalOptions && !hasCommands && !hasPotentialCommands) {
let appId = '';
let appSecret = '';
let userId = '';
for (let i = 0; i < args.length; i++) {
if (args[i] === '--appId' && i + 1 < args.length) {
appId = args[i + 1] || '';
}
else if (args[i] === '--appSecret' && i + 1 < args.length) {
appSecret = args[i + 1] || '';
}
else if (args[i] === '--userId' && i + 1 < args.length) {
userId = args[i + 1] || '';
}
}
if (!appId)
appId = process.env['POLYV_APP_ID'] || '';
if (!appSecret)
appSecret = process.env['POLYV_APP_SECRET'] || '';
if (!userId)
userId = process.env['POLYV_USER_ID'] || '';
const hasAuthOptions = appId || appSecret || userId;
if (hasAuthOptions && (!appId || !appSecret)) {
try {
const { authAdapter } = require('./config/auth-adapter');
const authResult = authAdapter.tryGetAuthConfig({});
if (!authResult) {
const statusMessage = authAdapter.getStatusMessage({});
console.error(statusMessage);
process.exit(1);
}
}
catch (error) {
console.error('Auth configuration is incomplete');
process.exit(1);
}
}
}
}
try {
program.parse();
}
catch (err) {
if (err.code === 'commander.version') {
process.exit(0);
}
if (err.code === 'commander.help' || err.code === 'commander.helpDisplayed') {
if (isHelpOrVersion) {
process.exit(0);
}
const registeredCommands = getAllRegisteredCommands();
const allKnownCommands = new Set([
...registeredCommands.topLevel,
...Array.from(registeredCommands.subCommands.values()).flat(),
'help'
]);
const potentialUnknownCommand = args.find((arg, index) => {
if (arg.startsWith('-'))
return false;
if (allKnownCommands.has(arg))
return false;
if (index > 0) {
const prevArg = args[index - 1];
if (prevArg && prevArg.startsWith('--'))
return false;
}
return true;
});
if (potentialUnknownCommand) {
try {
await loadAndValidateConfig(program);
}
catch (configError) {
(0, errors_1.logError)(configError instanceof Error ? configError : new Error(String(configError)));
process.exit(1);
}
console.error(`Unknown command: ${potentialUnknownCommand}`);
console.error('Run --help to see available commands');
process.exit(1);
}
const options = program.opts();
const hasAuthOptions = options['appId'] || options['appSecret'] || options['userId'];
if (hasAuthOptions && (!options['appId'] || !options['appSecret'])) {
try {
const { authAdapter } = require('./config/auth-adapter');
const authResult = authAdapter.tryGetAuthConfig(options);
if (!authResult) {
const statusMessage = authAdapter.getStatusMessage(options);
console.error(statusMessage);
process.exit(1);
}
}
catch (error) {
console.error('Auth configuration is incomplete');
process.exit(1);
}
}
showQuickHelp();
process.exit(0);
}
if (err.code === 'commander.version') {
process.exit(0);
}
if (err.code && err.code.startsWith('commander.')) {
if (err.message && err.message !== '(outputHelp)') {
console.error(err.message);
}
process.exit(err.exitCode || 1);
}
throw err;
}
const hasOnlyGlobalOptions = args.every(arg => {
if (arg.startsWith('-')) {
return arg.startsWith('--appId') || arg.startsWith('--appSecret') || arg.startsWith('--userId') ||
arg.startsWith('--environment') || arg.startsWith('--debug') || arg.startsWith('--timeout') ||
arg.startsWith('--baseUrl') || arg.startsWith('--maxRetries') || arg.startsWith('--config');
}
const argIndex = args.indexOf(arg);
if (argIndex > 0) {
const prevArg = args[argIndex - 1];
return prevArg === '--appId' || prevArg === '--appSecret' || prevArg === '--userId' ||
prevArg === '--environment' || prevArg === '--timeout' ||
prevArg === '--baseUrl' || prevArg === '--maxRetries' || prevArg === '--config';
}
return false;
});
if (hasOnlyGlobalOptions) {
const options = program.opts();
const hasAuthOptions = options['appId'] || options['appSecret'] || options['userId'];
if (hasAuthOptions && (!options['appId'] || !options['appSecret'])) {
try {
const { authAdapter } = require('./config/auth-adapter');
const authResult = authAdapter.tryGetAuthConfig(options);
if (!authResult) {
const statusMessage = authAdapter.getStatusMessage(options);
console.error(statusMessage);
process.exit(1);
}
}
catch (error) {
console.error('Auth configuration is incomplete');
process.exit(1);
}
}
showQuickHelp();
return;
}
if (!unknownCommand) {
const commandPathIndices = getCommandPathIndices(args);
unknownCommand = args.find((arg, index) => {
if (arg.startsWith('-'))
return false;
if (arg === 'help')
return false;
if (commandPathIndices.has(index))
return false;
if (isOptionValue(args, index))
return false;
return true;
}) || null;
}
if (unknownCommand) {
const options = program.opts();
const appId = options['appId'] || process.env['POLYV_APP_ID'];
const appSecret = options['appSecret'] || process.env['POLYV_APP_SECRET'];
const hasAnyAuthOptions = options['appId'] || options['appSecret'] || options['userId'] ||
process.env['POLYV_APP_ID'] || process.env['POLYV_APP_SECRET'] || process.env['POLYV_USER_ID'];
if (hasAnyAuthOptions && (!appId || !appSecret)) {
try {
const { authAdapter } = require('./config/auth-adapter');
const authResult = authAdapter.tryGetAuthConfig(options);
if (!authResult) {
const statusMessage = authAdapter.getStatusMessage(options);
console.error(statusMessage);
process.exit(1);
}
}
catch (error) {
console.error('Auth configuration is incomplete');
process.exit(1);
}
}
if (!hasAnyAuthOptions) {
try {
const { authAdapter } = require('./config/auth-adapter');
const authResult = authAdapter.tryGetAuthConfig(options);
if (!authResult) {
const statusMessage = authAdapter.getStatusMessage(options);
console.error(statusMessage);
process.exit(1);
}
}
catch (error) {
console.error('Auth configuration is incomplete');
process.exit(1);
}
}
console.error(`Unknown command: ${unknownCommand}`);
console.error('Run --help to see available commands');
process.exit(1);
}
if (!isHelpOrVersion) {
const hasActualCommands = getCommandPathIndices(args).size > 0;
if (unknownCommand && !hasActualCommands) {
try {
const config = await loadAndValidateConfig(program);
if (!config) {
console.error(`Unknown command: ${unknownCommand}`);
console.error('Run --help to see available commands');
process.exit(1);
}
}
catch (configError) {
(0, errors_1.logError)(configError instanceof Error ? configError : new Error(String(configError)));
process.exit(1);
}
console.error(`Unknown command: ${unknownCommand}`);
console.error('Run --help to see available commands');
process.exit(1);
}
if (hasActualCommands) {
return;
}
showQuickHelp();
}
}
if (require.main === module) {
main().catch(error => {
(0, errors_1.logError)(error);
process.exit(1);
});
}
function extractCommands(program) {
const topLevel = [];
const subCommands = new Map();
if (program.commands && Array.isArray(program.commands)) {
program.commands.forEach(cmd => {
topLevel.push(cmd.name());
if (cmd.commands && cmd.commands.length > 0) {
const subCmdNames = cmd.commands.map((subcmd) => subcmd.name());
subCommands.set(cmd.name(), subCmdNames);
}
});
}
return { topLevel, subCommands };
}
//# sourceMappingURL=index.js.map