@vfarcic/dot-ai
Version:
AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance
113 lines (112 loc) • 4.59 kB
JavaScript
;
/**
* ArtifactHub API Client
*
* Handles searching and retrieving Helm chart information from ArtifactHub
* API Documentation: https://artifacthub.io/docs/api/
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArtifactHubService = void 0;
/**
* ArtifactHub API client for Helm chart discovery
*/
class ArtifactHubService {
baseUrl = 'https://artifacthub.io/api/v1';
timeout = 10000; // 10 seconds
// Repositories to exclude from search results
// Bitnami charts often have non-standard configurations
excludedRepos = ['bitnami'];
/**
* Search for Helm charts matching the query
*
* @param query - Search query (e.g., "argo cd", "prometheus")
* @param limit - Maximum number of results to return
* @returns Array of search results sorted by relevance (excludes Bitnami)
*/
async searchCharts(query, limit = 10) {
const encodedQuery = encodeURIComponent(query);
// kind=0 filters for Helm charts only
const url = `${this.baseUrl}/packages/search?ts_query_web=${encodedQuery}&kind=0&limit=${limit}`;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = await fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`ArtifactHub API error: ${response.status} ${response.statusText}`);
}
const data = (await response.json());
// Filter out excluded repositories (e.g., Bitnami)
const packages = data.packages || [];
return packages.filter(pkg => !this.excludedRepos.includes(pkg.repository.name.toLowerCase()));
}
catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`ArtifactHub API timeout after ${this.timeout}ms`, {
cause: error,
});
}
throw new Error(`ArtifactHub search failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
}
}
/**
* Get detailed information about a specific chart
*
* @param repoName - Repository name (e.g., "argo")
* @param chartName - Chart name (e.g., "argo-cd")
* @returns Detailed chart information including README and values schema
*/
async getChartDetails(repoName, chartName) {
const url = `${this.baseUrl}/packages/helm/${repoName}/${chartName}`;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = await fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`ArtifactHub API error: ${response.status} ${response.statusText}`);
}
return (await response.json());
}
catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`ArtifactHub API timeout after ${this.timeout}ms`, {
cause: error,
});
}
throw new Error(`ArtifactHub chart details failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
}
}
/**
* Format chart results for AI analysis prompt
*
* @param charts - Array of ArtifactHub search results
* @returns Formatted string for AI prompt
*/
formatChartsForAI(charts) {
return charts
.map((chart, index) => `
Chart ${index + 1}: ${chart.name}
Repository: ${chart.repository.name} (${chart.repository.url})
Version: ${chart.version}${chart.app_version ? ` (App: ${chart.app_version})` : ''}
Description: ${chart.description || 'No description'}
Official: ${chart.official || chart.repository.official ? 'Yes' : 'No'}
Verified Publisher: ${chart.verified_publisher || chart.repository.verified_publisher ? 'Yes' : 'No'}
Stars: ${chart.stars}
`)
.join('\n');
}
}
exports.ArtifactHubService = ArtifactHubService;