import upath from 'upath'; import { logger } from '../../../logger/index.ts'; import { regEx } from '../../../util/regex.ts'; import { parseUrl } from '../../../util/url.ts'; import type { PackageDependency } from '../types.ts'; import { getOciChartDep } from './oci.ts'; import type { ChartDefinition, Repository } from './types.ts'; export function parseRepository( depName: string, repositoryURL: string, ): PackageDependency { const res: PackageDependency = {}; const url = parseUrl(repositoryURL); if (!url) { logger.debug({ repositoryURL }, 'Error parsing url'); res.skipReason = 'invalid-url'; return res; } switch (url.protocol) { case 'oci:': return getOciChartDep(repositoryURL, depName); case 'file:': res.skipReason = 'local-dependency'; break; default: res.registryUrls = [repositoryURL]; } return res; } /** * Resolves alias in repository string. * * @param repository to be resolved string * @param registryAliases Records containing registryAliases as key and to be resolved URLs as values * * @returns resolved alias. If repository does not contain an alias the repository string will be returned. Should it contain an alias which can not be resolved using `registryAliases`, null will be returned */ export function resolveAlias( repository: string, registryAliases: Record, ): string | null { if (!isAlias(repository)) { return repository; } const repoWithPrefixRemoved = repository.slice( repository.startsWith('@') ? 1 : 6, ); const alias = registryAliases[repoWithPrefixRemoved]; if (alias) { return alias; } return null; } export function getRepositories(definitions: ChartDefinition[]): Repository[] { const repositoryList = definitions .flatMap((value) => value.dependencies) .filter((dependency) => dependency.repository) // only keep non-local references --> if no repository is defined the chart will be searched in charts/ .filter((dependency) => !isAlias(dependency.repository)) // do not add registryAliases .filter((dependency) => !dependency.repository.startsWith('file:')) // skip repositories which are locally referenced .map((dependency) => { // remove additional keys to prevent interference at deduplication return { name: dependency.name, repository: dependency.repository, }; }); const dedup = new Set(); return repositoryList.filter((el) => { const duplicate = dedup.has(el.repository); dedup.add(el.repository); return !duplicate; }); } export function isAlias(repository: string): boolean { if (!repository) { return false; } return repository.startsWith('@') || repository.startsWith('alias:'); } export function aliasRecordToRepositories( registryAliases: Record, ): Repository[] { return Object.entries(registryAliases) .filter(([, url]) => regEx(/^(?:https?|oci):\/\/.+/).exec(url)) .map(([alias, url]) => { return { name: alias, repository: url, }; }); } export function isFileInDir(dir: string, file: string): boolean { return upath.dirname(file) === dir; }