UNPKG

@interopio/desktop-cli

Version:

io.Connect Desktop Seed Repository CLI Tools

179 lines 8.54 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpStorage = void 0; const axios_1 = __importDefault(require("axios")); const utils_1 = require("../../utils"); const component_downloader_1 = require("../component-downloader"); const iocd_config_1 = require("./config/iocd-config"); const component_registry_1 = require("../component-registry"); /** * HTTP/HTTPS storage implementation for downloading components from web URLs * Configuration via .iocdrc file or environment variables */ class HttpStorage { constructor() { this.downloader = component_downloader_1.ComponentDownloader.fromEnvironment(); this.config = null; // Configuration will be loaded lazily } /** * Get configuration, loading it if necessary */ async getConfig() { if (!this.config) { this.config = await iocd_config_1.IocdConfigManager.loadConfig(); } return this.config; } async getAvailableComponents(platform, arch) { const results = []; // Use hardcoded component registry to list all available components for (const componentName of (0, component_registry_1.getAllComponentNames)()) { const definition = (0, component_registry_1.getComponentDefinition)(componentName); if (!definition) continue; // Check if component supports this platform if (!(0, component_registry_1.isComponentSupported)(componentName, platform)) { utils_1.Logger.debug(`Component ${componentName} does not support platform ${platform}`, 'storage'); continue; } // Add component to results (don't verify availability for listing) results.push({ name: componentName, version: 'latest', // Use default version for listing description: definition.description, source: 'http', licenseRequired: definition.licenseRequired, platforms: definition.platforms }); } utils_1.Logger.debug(`Found ${results.length} components for platform ${platform}`, 'storage'); return results; } async getComponentMetadata(componentName, version) { const platform = process.platform; // Use built-in component registry instead of config const definition = (0, component_registry_1.getComponentDefinition)(componentName); if (!definition) { throw new Error(`Unknown component: ${componentName}. Available components: ${(0, component_registry_1.getAllComponentNames)().join(', ')}`); } // Check if component supports this platform if (!(0, component_registry_1.isComponentSupported)(componentName, platform)) { throw new Error(`Component ${componentName} is not available for platform: ${platform}`); } return { name: componentName, version, description: definition.description, source: 'http', licenseRequired: definition.licenseRequired, platforms: definition.platforms }; } async getLatestVersion(componentName) { const definition = (0, component_registry_1.getComponentDefinition)(componentName); if (!definition) { throw new Error(`Component ${componentName} not found in registry`); } // For HTTP storage, we'll use 'latest' as the default version // This can be enhanced later to query actual version endpoints return 'latest'; } buildDownloadUrl(componentName, version, platform, arch) { return this.buildDownloadUrlSync(componentName, version, platform, arch); } buildDownloadUrlSync(componentName, version, platform, arch) { if (!this.config) { throw new Error('Configuration not loaded. Call getConfig() first.'); } const definition = (0, component_registry_1.getComponentDefinition)(componentName); if (!definition) { throw new Error(`Unknown component: ${componentName}. Component not found in registry`); } const fileName = this.getFileName(componentName, version, platform, arch); const baseName = definition.fileName || componentName; // Use URL pattern if provided if (this.config.http?.urlPattern) { const extension = this.getFileExtension(platform); return this.config.http.urlPattern .replace('{component}', componentName) .replace('{fileName}', baseName) .replace('{version}', version) .replace('{platform}', platform) .replace('{arch}', arch) .replace('{file}', fileName) .replace('{ext}', extension.substring(1)); // Remove leading dot } // Use base URL + simple path construction if (this.config.http?.baseUrl) { const baseUrl = this.config.http.baseUrl.replace(/\/$/, ''); const url = `${baseUrl}/${fileName}`; utils_1.Logger.debug(`Built HTTP URL: ${url}`, 'storage'); return url; } throw new Error('No HTTP URL configuration found. Configure baseUrl or urlPattern in .iocdrc'); } async componentExists(componentName, version, platform, arch) { try { await this.getConfig(); // Ensure config is loaded const url = this.buildDownloadUrlSync(componentName, version, platform, arch); const config = await this.getConfig(); // Make a HEAD request to check if the resource exists const response = await axios_1.default.head(url, { timeout: config.http?.timeout || 10000, headers: config.http?.headers || {}, validateStatus: (status) => status < 500 // Accept 4xx as "doesn't exist" }); return response.status >= 200 && response.status < 300; } catch (error) { utils_1.Logger.debug(`Component existence check failed for ${componentName}@${version}: ${error instanceof Error ? error.message : String(error)}`, 'storage'); return false; } } async downloadComponent(component, version, outputDir) { try { const config = await this.getConfig(); const platform = process.platform; const arch = process.arch; const downloadUrl = this.buildDownloadUrlSync(component.name, version, platform, arch); utils_1.Logger.info(`Downloading ${component.name}@${version} from HTTP...`); utils_1.Logger.debug(`Download URL: ${downloadUrl}`, 'storage'); // Use the shared ComponentDownloader with configuration return await this.downloader.downloadComponent({ url: downloadUrl, targetPath: outputDir, useCache: config.settings?.useCache ?? true, maxRetries: config.http?.maxRetries ?? 3, timeout: config.http?.timeout ?? 300000, headers: config.http?.headers }); } catch (error) { utils_1.Logger.error(`Failed to download component from HTTP: ${error instanceof Error ? error.message : String(error)}`); throw new Error(`HTTP download failed: ${error instanceof Error ? error.message : String(error)}`); } } getFileName(componentName, version, platform, arch) { const definition = (0, component_registry_1.getComponentDefinition)(componentName); const baseName = definition?.fileName || componentName; const extension = this.getFileExtension(platform); const prefixedVersion = version === "latest" ? version : `v${version}`; const fileName = `${baseName}-${prefixedVersion}-${platform}-${arch}${extension}`; utils_1.Logger.debug(`Generated filename for ${componentName}: ${fileName}`, 'storage'); return fileName; } getFileExtension(platform) { switch (platform) { case 'win32': return '.zip'; case 'darwin': return '.dmg'; case 'linux': return '.tar.gz'; default: return '.zip'; } } } exports.HttpStorage = HttpStorage; //# sourceMappingURL=http-storage.js.map