Files
Sebastian Poxhofer 15f4bd8eff chore: migrate from zod/v3 to zod/v4 (#43691)
* chore: migrate from zod/v3 to zod/v4

This commit contains the logic changes

* chore: migrate imports from zod/v3 to zod/v4

This contains import updates and adds explicit record keys as zod/v4 requires these now

* ci: enforce usage of zod/v4
2026-05-30 16:01:58 +00:00

75 lines
1.9 KiB
TypeScript

import { isPlainObject } from '@sindresorhus/is';
import { z } from 'zod/v4';
import { LooseArray } from '../../../util/schema-utils/index.ts';
import { MaybeTimestamp } from '../../../util/timestamp.ts';
import type { Release, ReleaseResult } from '../types.ts';
export const HexRelease = z
.object({
html_url: z.string().optional(),
meta: z
.object({
links: z
.record(z.string(), z.string())
.transform((links) =>
Object.fromEntries(
Object.entries(links).map(([key, value]) => [
key.toLowerCase(),
value,
]),
),
)
.pipe(
z.object({
github: z.string(),
}),
),
})
.nullable()
.catch(null),
releases: LooseArray(
z.object({
version: z.string(),
inserted_at: MaybeTimestamp,
}),
).refine((releases) => releases.length > 0, 'No releases found'),
retirements: z
.record(
z.string(),
z.object({
message: z.string().nullable(),
reason: z.string(),
}),
)
.optional(),
})
.transform((hexResponse): ReleaseResult => {
const releases: Release[] = hexResponse.releases.map(
({ version, inserted_at: releaseTimestamp }): Release => {
const release: Release = { version };
if (releaseTimestamp) {
release.releaseTimestamp = releaseTimestamp;
}
if (isPlainObject(hexResponse.retirements?.[version])) {
release.isDeprecated = true;
}
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;
});