mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-01 10:09:50 +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>
124 lines
2.9 KiB
TypeScript
124 lines
2.9 KiB
TypeScript
import { z } from 'zod/v4';
|
|
import { DeepNullish, EmailAddress } from '../../../util/schema-utils/index.ts';
|
|
|
|
export const User = z.object({
|
|
mail: EmailAddress,
|
|
displayName: z.string(),
|
|
name: z.string(),
|
|
});
|
|
export type User = z.infer<typeof User>;
|
|
|
|
export const DefaultBranch = z.object({
|
|
defaultBranch: z.string(),
|
|
});
|
|
|
|
export const Link = DeepNullish(
|
|
z.object({
|
|
href: z.string(),
|
|
name: z.string().optional(),
|
|
templated: z.boolean().optional(),
|
|
}),
|
|
);
|
|
export type Link = z.infer<typeof Link>;
|
|
|
|
export const Links = z.record(z.string(), z.union([Link, z.array(Link)]));
|
|
export type Links = z.infer<typeof Links>;
|
|
|
|
export const PrState = z.enum(['DRAFT', 'OPEN', 'REJECTED', 'MERGED']);
|
|
export type PrState = z.infer<typeof PrState>;
|
|
|
|
export const PrMergeMethod = z.enum([
|
|
'MERGE_COMMIT',
|
|
'REBASE',
|
|
'FAST_FORWARD_IF_POSSIBLE',
|
|
'FAST_FORWARD_ONLY',
|
|
'SQUASH',
|
|
]);
|
|
export type PrMergeMethod = z.infer<typeof PrMergeMethod>;
|
|
|
|
export const PullRequest = DeepNullish(
|
|
z.object({
|
|
id: z.string(),
|
|
author: z
|
|
.object({
|
|
mail: z.string().optional(),
|
|
displayName: z.string(),
|
|
id: z.string(),
|
|
})
|
|
.optional(),
|
|
reviser: z
|
|
.object({
|
|
id: z.string().optional(),
|
|
displayName: z.string().optional(),
|
|
})
|
|
.optional(),
|
|
closeDate: z.string().optional(),
|
|
source: z.string(),
|
|
target: z.string(),
|
|
title: z.string(),
|
|
description: z.string().optional(),
|
|
creationDate: z.string(),
|
|
lastModified: z.string().optional(),
|
|
status: PrState,
|
|
reviewer: z
|
|
.array(
|
|
z.object({
|
|
id: z.string(),
|
|
displayName: z.string(),
|
|
mail: z.string().optional(),
|
|
approved: z.boolean(),
|
|
}),
|
|
)
|
|
.optional(),
|
|
labels: z.string().array(),
|
|
tasks: z.object({
|
|
todo: z.number(),
|
|
done: z.number(),
|
|
}),
|
|
_links: Links,
|
|
_embedded: z.object({
|
|
defaultConfig: z.object({
|
|
mergeStrategy: PrMergeMethod,
|
|
deleteBranchOnMerge: z.boolean(),
|
|
}),
|
|
}),
|
|
}),
|
|
);
|
|
export type PullRequest = z.infer<typeof PullRequest>;
|
|
|
|
const RepoType = z.enum(['git', 'svn', 'hg']);
|
|
|
|
export const Repo = DeepNullish(
|
|
z.object({
|
|
contact: z.string().optional(),
|
|
creationDate: z.string().optional(),
|
|
description: z.string().optional(),
|
|
lastModified: z.string().optional(),
|
|
namespace: z.string(),
|
|
name: z.string(),
|
|
type: RepoType,
|
|
archived: z.boolean(),
|
|
exporting: z.boolean(),
|
|
healthCheckRunning: z.boolean(),
|
|
_links: Links,
|
|
}),
|
|
);
|
|
export type Repo = z.infer<typeof Repo>;
|
|
|
|
const Paged = z.object({
|
|
page: z.number(),
|
|
pageTotal: z.number(),
|
|
});
|
|
|
|
export const PagedPullRequest = Paged.extend({
|
|
_embedded: z.object({
|
|
pullRequests: z.array(PullRequest),
|
|
}),
|
|
});
|
|
|
|
export const PagedRepo = Paged.extend({
|
|
_embedded: z.object({
|
|
repositories: z.array(Repo),
|
|
}),
|
|
});
|