@interopio/desktop-cli
Version:
io.Connect Desktop Seed Repository CLI Tools
179 lines • 8.54 kB
JavaScript
;
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