import CloudRunnerLogger from '../services/core/cloud-runner-logger'; export interface GitHubUrlInfo { type: 'github'; owner: string; repo: string; branch?: string; path?: string; url: string; } export interface LocalPathInfo { type: 'local'; path: string; } export interface NpmPackageInfo { type: 'npm'; packageName: string; } export type ProviderSourceInfo = GitHubUrlInfo | LocalPathInfo | NpmPackageInfo; /** * Parses a provider source string and determines its type and details * @param source The provider source string (URL, path, or package name) * @returns ProviderSourceInfo object with parsed details */ export function parseProviderSource(source: string): ProviderSourceInfo { // Check if it's a GitHub URL const githubMatch = source.match( /^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?(?:tree\/([^/]+))?(?:\/(.+))?$/, ); if (githubMatch) { const [, owner, repo, branch, path] = githubMatch; return { type: 'github', owner, repo, branch: branch || 'main', path: path || '', url: `https://github.com/${owner}/${repo}`, }; } // Check if it's a GitHub SSH URL const githubSshMatch = source.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?\/?(?:tree\/([^/]+))?(?:\/(.+))?$/); if (githubSshMatch) { const [, owner, repo, branch, path] = githubSshMatch; return { type: 'github', owner, repo, branch: branch || 'main', path: path || '', url: `https://github.com/${owner}/${repo}`, }; } // Check if it's a shorthand GitHub reference (owner/repo) const shorthandMatch = source.match(/^([^/@]+)\/([^/@]+)(?:@([^/]+))?(?:\/(.+))?$/); if (shorthandMatch && !source.startsWith('.') && !source.startsWith('/') && !source.includes('\\')) { const [, owner, repo, branch, path] = shorthandMatch; return { type: 'github', owner, repo, branch: branch || 'main', path: path || '', url: `https://github.com/${owner}/${repo}`, }; } // Check if it's a local path if (source.startsWith('./') || source.startsWith('../') || source.startsWith('/') || source.includes('\\')) { return { type: 'local', path: source, }; } // Default to npm package return { type: 'npm', packageName: source, }; } /** * Generates a cache key for a GitHub repository * @param urlInfo GitHub URL information * @returns Cache key string */ export function generateCacheKey(urlInfo: GitHubUrlInfo): string { return `github_${urlInfo.owner}_${urlInfo.repo}_${urlInfo.branch}`.replace(/[^\w-]/g, '_'); } /** * Validates if a string looks like a valid GitHub URL or reference * @param source The source string to validate * @returns True if it looks like a GitHub reference */ export function isGitHubSource(source: string): boolean { const parsed = parseProviderSource(source); return parsed.type === 'github'; } /** * Logs the parsed provider source information * @param source The original source string * @param parsed The parsed source information */ export function logProviderSource(source: string, parsed: ProviderSourceInfo): void { CloudRunnerLogger.log(`Provider source: ${source}`); switch (parsed.type) { case 'github': CloudRunnerLogger.log(` Type: GitHub repository`); CloudRunnerLogger.log(` Owner: ${parsed.owner}`); CloudRunnerLogger.log(` Repository: ${parsed.repo}`); CloudRunnerLogger.log(` Branch: ${parsed.branch}`); if (parsed.path) { CloudRunnerLogger.log(` Path: ${parsed.path}`); } break; case 'local': CloudRunnerLogger.log(` Type: Local path`); CloudRunnerLogger.log(` Path: ${parsed.path}`); break; case 'npm': CloudRunnerLogger.log(` Type: NPM package`); CloudRunnerLogger.log(` Package: ${parsed.packageName}`); break; } }