diff --git a/lib/modules/datasource/hex/index.ts b/lib/modules/datasource/hex/index.ts index 8e45bd491ab6c3d1de5853502b521b31d2fde568..e6ee7d927cc364b73b1d40c10005a9236aee67de 100644 --- a/lib/modules/datasource/hex/index.ts +++ b/lib/modules/datasource/hex/index.ts @@ -1,10 +1,9 @@ import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; -import type { HttpResponse } from '../../../util/http/types'; import * as hexVersioning from '../../versioning/hex'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; -import type { HexRelease } from './types'; +import { HexRelease } from './schema'; export class HexDatasource extends Datasource { static readonly id = 'hex'; @@ -43,44 +42,15 @@ export class HexDatasource extends Datasource { : ''; const hexUrl = `${registryUrl}api/${organizationUrlPrefix}packages/${hexPackageName}`; - let response: HttpResponse<HexRelease>; - try { - response = await this.http.getJson<HexRelease>(hexUrl); - } catch (err) { - this.handleGenericErrors(err); - } - - const hexRelease: HexRelease = response.body; - - if (!hexRelease) { - logger.warn({ datasource: 'hex', packageName }, `Invalid response body`); - return null; - } - - const { releases = [], html_url: homepage, meta } = hexRelease; + const { val: result, err } = await this.http + .getJsonSafe(hexUrl, HexRelease) + .onError((err) => { + logger.warn({ datasource: 'hex', packageName, err }, `Error fetching ${hexUrl}`); // prettier-ignore + }) + .unwrap(); - if (releases.length === 0) { - logger.debug(`No versions found for ${hexPackageName} (${hexUrl})`); // prettier-ignore - return null; - } - - const result: ReleaseResult = { - releases: releases.map(({ version, inserted_at }) => - inserted_at - ? { - version, - releaseTimestamp: inserted_at, - } - : { version }, - ), - }; - - if (homepage) { - result.homepage = homepage; - } - - if (meta?.links?.Github) { - result.sourceUrl = meta?.links?.Github; + if (err) { + this.handleGenericErrors(err); } return result; diff --git a/lib/modules/datasource/hex/schema.ts b/lib/modules/datasource/hex/schema.ts new file mode 100644 index 0000000000000000000000000000000000000000..b1015ae664d0656811cbc575e9ce692a63e1a6e1 --- /dev/null +++ b/lib/modules/datasource/hex/schema.ts @@ -0,0 +1,47 @@ +import { z } from 'zod'; +import { LooseArray } from '../../../util/schema-utils'; +import type { Release, ReleaseResult } from '../types'; + +export const HexRelease = z + .object({ + html_url: z.string().optional(), + meta: z + .object({ + links: z.object({ + Github: z.string(), + }), + }) + .nullable() + .catch(null), + releases: LooseArray( + z.object({ + version: z.string(), + inserted_at: z.string().optional(), + }), + ).refine((releases) => releases.length > 0, 'No releases found'), + }) + .transform((hexResponse): ReleaseResult => { + const releases: Release[] = hexResponse.releases.map( + ({ version, inserted_at: releaseTimestamp }): Release => { + const release: Release = { version }; + + if (releaseTimestamp) { + release.releaseTimestamp = releaseTimestamp; + } + + return release; + }, + ); + + const releaseResult: ReleaseResult = { releases }; + + if (hexResponse.html_url) { + releaseResult.homepage = hexResponse.html_url; + } + + if (hexResponse.meta?.links?.Github) { + releaseResult.sourceUrl = hexResponse.meta.links.Github; + } + + return releaseResult; + }); diff --git a/lib/modules/datasource/hex/types.ts b/lib/modules/datasource/hex/types.ts deleted file mode 100644 index bf7eadc7976560f9f372dc3a8c83550765fecd7e..0000000000000000000000000000000000000000 --- a/lib/modules/datasource/hex/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface HexRelease { - html_url: string; - meta?: { links?: Record<string, string> }; - releases?: { - version: string; - inserted_at?: string; - }[]; -}