UNPKG

leshi-ui

Version:

Modern CLI for building and managing React Native UI components with copy-paste simplicity, custom theming, and open source design system support

146 lines (145 loc) 5.66 kB
import { Logger } from '../utils/logger.js'; import { VersionUtils } from '../utils/version.js'; export class GitHubService { static REPO_OWNER = 'AgustinOberg'; static REPO_NAME = 'leshi-ui'; static BASE_URL = `https://api.github.com/repos/${this.REPO_OWNER}/${this.REPO_NAME}`; static registryCache = null; static gitHubRef = null; static async getGitHubRef() { if (this.gitHubRef) { return this.gitHubRef; } this.gitHubRef = await VersionUtils.getGitHubRef(); return this.gitHubRef; } static async getRawBaseUrl() { const ref = await this.getGitHubRef(); return `https://raw.githubusercontent.com/${this.REPO_OWNER}/${this.REPO_NAME}/${ref}`; } static async getRegistry() { if (this.registryCache) { return this.registryCache; } try { const rawBaseUrl = await this.getRawBaseUrl(); const registryUrl = `${rawBaseUrl}/cli/component-registry.json`; const response = await fetch(registryUrl); if (!response.ok) { throw new Error(`Failed to fetch registry: ${response.status} ${response.statusText}`); } const registryData = await response.json(); this.registryCache = registryData; return registryData; } catch (error) { Logger.error('Failed to load component registry from GitHub'); throw error; } } static async downloadComponent(framework, componentName) { try { const rawBaseUrl = await this.getRawBaseUrl(); const componentPath = `packages/${framework}/components/ui/${componentName}.tsx`; const fileUrl = `${rawBaseUrl}/${componentPath}`; const response = await fetch(fileUrl); if (!response.ok) { throw new Error(`Failed to download component '${componentName}': ${response.status} ${response.statusText}`); } return await response.text(); } catch (error) { Logger.error(`Failed to download component '${componentName}' from GitHub`); throw error; } } static async downloadUtility(framework, utilityPath) { try { const rawBaseUrl = await this.getRawBaseUrl(); const filename = utilityPath.split('/').pop(); const fileUrl = `${rawBaseUrl}/packages/${framework}/lib/${filename}`; const response = await fetch(fileUrl); if (!response.ok) { throw new Error(`Failed to download utility '${filename}': ${response.status} ${response.statusText}`); } return await response.text(); } catch (error) { Logger.error(`Failed to download utility '${utilityPath}' from GitHub`); throw error; } } static async downloadTheme(framework, themeName) { try { const rawBaseUrl = await this.getRawBaseUrl(); const themeUrl = `${rawBaseUrl}/packages/${framework}/styles/themes/${themeName}.ts`; const response = await fetch(themeUrl); if (!response.ok) { throw new Error(`Failed to download theme '${themeName}': ${response.status} ${response.statusText}`); } return await response.text(); } catch (error) { Logger.error(`Failed to download theme '${themeName}' from GitHub`); throw error; } } static async downloadStyleFiles(framework) { const files = {}; try { const rawBaseUrl = await this.getRawBaseUrl(); const styleFiles = [ 'theme.ts', 'context.tsx', ...(framework === 'rn' ? ['theme.d.ts'] : ['breakpoints.ts']) ]; for (const filename of styleFiles) { const fileUrl = `${rawBaseUrl}/packages/${framework}/styles/${filename}`; const response = await fetch(fileUrl); if (response.ok) { files[filename] = await response.text(); } } return files; } catch (error) { Logger.error(`Failed to download style files from GitHub`); throw error; } } static async getAvailableThemes(framework) { try { const ref = await this.getGitHubRef(); const apiUrl = `${this.BASE_URL}/contents/packages/${framework}/styles/themes?ref=${ref}`; const response = await fetch(apiUrl); if (!response.ok) { throw new Error(`Failed to fetch themes: ${response.status} ${response.statusText}`); } const files = await response.json(); return files .filter(file => file.type === 'file' && file.name.endsWith('.ts') && file.name !== 'index.ts' && file.name !== 'common.ts') .map(file => file.name.replace('.ts', '')); } catch (error) { Logger.error('Failed to fetch available themes from GitHub'); throw error; } } static async isRepositoryAccessible() { try { const response = await fetch(`${this.BASE_URL}`, { method: 'HEAD' }); return response.ok; } catch { return false; } } static clearCache() { this.registryCache = null; this.gitHubRef = null; } static async getCurrentRef() { return await this.getGitHubRef(); } }