fix: reject non-json model values

This commit is contained in:
vince 2026-06-18 17:49:18 +02:00
parent 74651a49de
commit b7c673bbd7
3 changed files with 72 additions and 3 deletions

View file

@ -55,11 +55,14 @@ export function validateDashboardDocument(
value: unknown,
): DashboardValidationResult {
const finiteNumberIssues: SemanticValidationIssue[] = [];
const undefinedIssues: SemanticValidationIssue[] = [];
collectFiniteNumberIssues(value, "", finiteNumberIssues);
collectUndefinedIssues(value, "", undefinedIssues);
if (validateDashboard(value)) {
const semanticIssues = [
...finiteNumberIssues,
...undefinedIssues,
...validateSemanticRules(value),
];
if (semanticIssues.length === 0) {
@ -73,7 +76,11 @@ export function validateDashboardDocument(
};
}
const details = [...(validateDashboard.errors || []), ...finiteNumberIssues];
const details = [
...(validateDashboard.errors || []),
...finiteNumberIssues,
...undefinedIssues,
];
return {
valid: false,
errors: formatValidationErrors(details),
@ -154,6 +161,16 @@ function validateSemanticRules(document: DashboardDocument): SemanticValidationI
);
document.telemetry.forEach((card, index) => {
if (card.value.kind === "text" && card.thresholds !== undefined) {
issues.push(
semanticIssue(
`/telemetry/${index}/thresholds`,
"must not be set for text metric values",
{ id: card.id },
),
);
}
const warning = card.thresholds?.warning;
const danger = card.thresholds?.danger;
if (warning !== undefined && danger !== undefined && warning > danger) {
@ -170,6 +187,32 @@ function validateSemanticRules(document: DashboardDocument): SemanticValidationI
return issues;
}
function collectUndefinedIssues(
value: unknown,
path: string,
issues: SemanticValidationIssue[],
) {
if (value === undefined) {
issues.push(
semanticIssue(path || "/", "must be omitted instead of undefined", {}),
);
return;
}
if (Array.isArray(value)) {
value.forEach((item, index) => {
collectUndefinedIssues(item, `${path}/${index}`, issues);
});
return;
}
if (value && typeof value === "object") {
Object.entries(value).forEach(([key, item]) => {
collectUndefinedIssues(item, `${path}/${escapeJsonPointer(key)}`, issues);
});
}
}
function collectFiniteNumberIssues(
value: unknown,
path: string,