mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-26 15:31:53 +00:00
a31f9cf0f9
* ci(linter): add renovate/prefer-zod-nullish rule Add a custom oxlint rule that flags zod chains calling .optional() and .nullable() adjacently (in either order) and suggests .nullish(), which is equivalent (both accept undefined | null in zod v4). Fix all 26 pre-existing violations across 6 schema files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(linter): prefer schema-utils Nullish over zod .nullish() Rename prefer-zod-nullish to prefer-nullish-util and extend it to flag .nullish() itself, including the standalone forms z.nullish(x) and z.optional(z.nullable(x)). Migrate all call sites to Nullish() and DeepNullish() from schema-utils, which normalize null to undefined in parsed output. Schemas with more than one nullish position are wrapped in DeepNullish(); nullish object properties with nullish members use Nullish(DeepNullish(...)) to keep the optional property type marker. Spec files are exempt (result.spec.ts intentionally tests null-preserving parses). Spec assertions expecting null in parsed output were updated to undefined. Note: docker manifests with an explicit "mediaType": null are now accepted and treated like an absent mediaType instead of failing the discriminated union. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import { isTruthy } from '@sindresorhus/is';
|
|
import { z } from 'zod/v4';
|
|
import { DeepNullish, LooseArray } from '../../../util/schema-utils/index.ts';
|
|
import { MaybeTimestamp } from '../../../util/timestamp.ts';
|
|
import type { Release, ReleaseResult } from '../types.ts';
|
|
|
|
export const PuppetReleaseAbbreviated = DeepNullish(
|
|
z.object({
|
|
version: z.string(),
|
|
created_at: MaybeTimestamp,
|
|
deleted_at: z.string().optional(),
|
|
file_uri: z.string().optional(),
|
|
}),
|
|
).transform(({ version, created_at, deleted_at, file_uri }): Release | null => {
|
|
if (deleted_at) {
|
|
return null;
|
|
}
|
|
|
|
const release: Release = { version };
|
|
if (file_uri) {
|
|
release.downloadUrl = file_uri;
|
|
}
|
|
if (created_at) {
|
|
release.releaseTimestamp = created_at;
|
|
}
|
|
return release;
|
|
});
|
|
|
|
export const PuppetModule = DeepNullish(
|
|
z.object({
|
|
releases: LooseArray(PuppetReleaseAbbreviated).default([]),
|
|
homepage_url: z.string().optional(),
|
|
deprecated_for: z.string().optional(),
|
|
}),
|
|
).transform((module): ReleaseResult => {
|
|
const releases = module.releases.filter(isTruthy);
|
|
const result: ReleaseResult = { releases };
|
|
if (module.homepage_url) {
|
|
result.homepage = module.homepage_url;
|
|
}
|
|
if (module.deprecated_for) {
|
|
result.deprecationMessage = module.deprecated_for;
|
|
}
|
|
return result;
|
|
});
|