import is from '@sindresorhus/is'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; import { HttpError } from '../../../util/http'; import { joinUrlParts } from '../../../util/url'; import { BzlmodVersion } from '../../versioning/bazel-module/bzlmod-version'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; import { BazelModuleMetadata } from './schema'; export class BazelDatasource extends Datasource { static readonly id = 'bazel'; static readonly bazelCentralRepoUrl = 'https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main'; override readonly defaultRegistryUrls = [BazelDatasource.bazelCentralRepoUrl]; override readonly registryStrategy = 'hunt'; override readonly customRegistrySupport = true; override readonly caching = true; static packageMetadataPath(packageName: string): string { return `/modules/${packageName}/metadata.json`; } constructor() { super(BazelDatasource.id); } @cache({ namespace: `datasource-${BazelDatasource.id}`, key: ({ registryUrl, packageName }: GetReleasesConfig) => `${registryUrl!}:${packageName}`, }) async getReleases({ registryUrl, packageName, }: GetReleasesConfig): Promise<ReleaseResult | null> { const path = BazelDatasource.packageMetadataPath(packageName); const url = joinUrlParts(registryUrl!, path); const result: ReleaseResult = { releases: [] }; try { const { body: metadata } = await this.http.getJson( url, BazelModuleMetadata ); result.releases = metadata.versions .map((v) => new BzlmodVersion(v)) .sort(BzlmodVersion.defaultCompare) .map((bv) => { const release: Release = { version: bv.original }; if (is.truthy(metadata.yanked_versions[bv.original])) { release.isDeprecated = true; } return release; }); } catch (err) { // istanbul ignore else: not testable with nock if (err instanceof HttpError) { if (err.response?.statusCode === 404) { return null; } throw new ExternalHostError(err); } this.handleGenericErrors(err); } return result.releases.length ? result : null; } }