UNPKG

@visionfi/server-cli

Version:

Command-line interface for VisionFI Server SDK

209 lines (208 loc) 9.53 kB
#!/usr/bin/env node /** * VisionFI Server CLI * Command-line interface for VisionFI Server SDK * The VisionFI Server CLI provides commands to manage packages and handle authentication. * It connects to the VisionFI API and allows users to perform various operations from the command line in a service to service pattern. * Copyright (c) 2024-2025 VisionFI. All Rights Reserved. */ import { Command } from 'commander'; import { verifyAuth, configureAuth, getToken, logout, showAuth } from './commands/auth.js'; import { createPackage, listPackages, getPackage, getPackageAudit, addExternalReferences, removeExternalReferences } from './commands/package.js'; import { addDocuments, deleteDocument } from './commands/document.js'; import { executeProcessing, getProcessingHistory, getProcessingResult, getProcessingView, pollProcessing } from './commands/processing.js'; import { getProductTypes, getWorkflows, getClientInfo } from './commands/admin.js'; import { Display } from './utils/display.js'; import { getConfigPath, loadConfig, saveConfig } from './utils/config.js'; import * as dotenv from 'dotenv'; import * as fs from 'fs'; // Load environment variables dotenv.config(); // Create the main program const program = new Command(); program .name('visionfi') .description('VisionFI Command Line Interface') .version('1.0.0'); // Auth command group const auth = program.command('auth') .description('Authentication commands'); auth.command('verify') .description('Verify authentication with VisionFI API') .action(verifyAuth); auth.command('configure') .description('Configure authentication settings') .option('--method <method>', 'Authentication method: file, adc, impersonate, or env') .option('--service-account-path <path>', 'Path to service account JSON file (when method=file)') .option('--impersonate-service-account <email>', 'Service account email to impersonate (when method=impersonate)') .action((options) => configureAuth(options)); auth.command('show') .description('Show current authentication configuration') .action(showAuth); auth.command('logout') .description('Clear authentication configuration') .action(logout); auth.command('token') .description('Get JWT authentication token') .action(getToken); // Package command group const pkg = program.command('package') .alias('pkg') .description('Package management commands'); pkg.command('create') .description('Create a new package') .requiredOption('--product-type <type>', 'Product type for the package') .requiredOption('--description <desc>', 'Package description') .option('--external-ref <ref...>', 'External reference IDs (array field)') .option('--ref1 <ref>', 'External reference 1 (exact match field)') .option('--ref2 <ref>', 'External reference 2 (exact match field)') .option('--ref3 <ref>', 'External reference 3 (exact match field)') .option('--ref4 <ref>', 'External reference 4 (exact match field)') .option('--ref5 <ref>', 'External reference 5 (exact match field)') .option('--category <category>', 'External category for semantic filtering') .option('--owner <owner>', 'External owner/department') .action(createPackage); pkg.command('list') .description('List packages') .option('--external-ref <ref>', 'Filter by external reference (deprecated, use --tags)') .option('--tags <tags>', 'Filter by tags (comma-separated, OR logic)') .option('--ref1 <ref>', 'Filter by external reference 1 (exact match)') .option('--ref2 <ref>', 'Filter by external reference 2 (exact match)') .option('--ref3 <ref>', 'Filter by external reference 3 (exact match)') .option('--ref4 <ref>', 'Filter by external reference 4 (exact match)') .option('--ref5 <ref>', 'Filter by external reference 5 (exact match)') .option('--category <category>', 'Filter by external category') .option('--owner <owner>', 'Filter by external owner') .option('--product-type <type>', 'Filter by product type') .option('--created-after <date>', 'Filter by creation date') .action(listPackages); pkg.command('get <packageId>') .description('Get package details') .action(getPackage); pkg.command('audit <packageId>') .description('Get package audit history') .option('--limit <n>', 'Limit number of audit entries') .action((packageId, options) => getPackageAudit(packageId, options)); // Package reference subcommands const pkgRef = pkg.command('ref') .description('External reference management'); pkgRef.command('add <packageId>') .description('Add external references to a package') .requiredOption('--refs <refs...>', 'External reference IDs to add') .action((packageId, options) => addExternalReferences(packageId, options)); pkgRef.command('remove <packageId>') .description('Remove external references from a package') .requiredOption('--refs <refs...>', 'External reference IDs to remove') .action((packageId, options) => removeExternalReferences(packageId, options)); // Package document subcommands const pkgDoc = pkg.command('document') .alias('doc') .description('Document management'); pkgDoc.command('add <packageId>') .description('Add documents to a package') .requiredOption('--file <path...>', 'File path(s) to add') .action((packageId, options) => addDocuments(packageId, options)); pkgDoc.command('delete <packageId> <documentId>') .description('Delete a document from a package') .action((packageId, documentId) => deleteDocument(packageId, documentId)); // Package processing subcommands const pkgProc = pkg.command('processing') .alias('proc') .description('Processing operations'); pkgProc.command('execute <packageId>') .description('Execute processing on a package') .option('--workflow <workflow>', 'Workflow to use') .action((packageId, options) => executeProcessing(packageId, options)); pkgProc.command('history <packageId>') .description('Get processing history') .option('--limit <n>', 'Limit number of results') .option('--with-results', 'Include processing results') .action((packageId, options) => getProcessingHistory(packageId, options)); pkgProc.command('result <packageId> <processingId>') .description('Get specific processing result') .action((packageId, processingId) => getProcessingResult(packageId, processingId)); pkgProc.command('view <packageId> <processingId>') .description('Get processing view') .option('--format <format>', 'View format') .action((packageId, processingId, options) => getProcessingView(packageId, processingId, options)); pkgProc.command('poll <packageId> <processingId>') .description('Poll for processing completion') .option('--timeout <ms>', 'Maximum wait time in milliseconds') .option('--interval <ms>', 'Poll interval in milliseconds') .action((packageId, processingId, options) => pollProcessing(packageId, processingId, options)); // Admin command group const admin = program.command('admin') .description('Administrative commands'); admin.command('products') .description('Get available product types') .action(getProductTypes); admin.command('workflows') .description('Get available workflows') .action(getWorkflows); admin.command('client') .description('Get client information') .action(getClientInfo); // Config command group const configCmd = program.command('config') .description('Configuration management'); configCmd.command('show') .description('Show configuration file location and contents') .action(() => { const configPath = getConfigPath(); Display.info(`Configuration file: ${configPath}`); if (fs.existsSync(configPath)) { try { const configContent = fs.readFileSync(configPath, 'utf-8'); Display.info(''); Display.info('Contents:'); console.log(configContent); } catch (error) { Display.error(`Failed to read config: ${error.message}`); } } else { Display.warning('Configuration file does not exist'); } }); configCmd.command('set') .description('Set configuration values') .option('--api-url <url>', 'Set the VisionFI API URL') .option('--audience <audience>', 'Set the token audience (default: platform.visionfi.ai)') .action((options) => { const config = loadConfig(); if (options.apiUrl) { config.apiUrl = options.apiUrl; Display.success(`API URL set to: ${options.apiUrl}`); } if (options.audience) { config.audience = options.audience; Display.success(`Audience set to: ${options.audience}`); } if (options.apiUrl || options.audience) { saveConfig(config); Display.info('Configuration saved'); } else { Display.error('No configuration values provided'); Display.info('Use --api-url or --audience'); process.exit(1); } }); configCmd.command('path') .description('Show configuration file path') .action(() => { Display.info(`Configuration file: ${getConfigPath()}`); }); // Handle unknown commands program.on('command:*', () => { Display.error(`Invalid command: ${program.args.join(' ')}`); Display.info('Run "visionfi --help" for a list of available commands'); process.exit(1); }); // Parse command line arguments program.parse(); // Show help if no command provided if (!process.argv.slice(2).length) { program.outputHelp(); }