mirror of https://github.com/buster-so/buster.git
Update validateMetricYaml.tsx
This commit is contained in:
parent
675379c00b
commit
16c6ea1d26
|
@ -2,8 +2,7 @@ import React, { useRef } from 'react';
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
import { type editor } from 'monaco-editor/esm/vs/editor/editor.api';
|
import { type editor } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
import { useEffect } from 'react';
|
import MonacoEditor from '@monaco-editor/react';
|
||||||
import MonacoEditor, { OnMount } from '@monaco-editor/react';
|
|
||||||
|
|
||||||
type IMarkerData = editor.IMarkerData;
|
type IMarkerData = editor.IMarkerData;
|
||||||
|
|
||||||
|
@ -15,8 +14,22 @@ Siblings:
|
||||||
Jane: 25
|
Jane: 25
|
||||||
Jim: 28`;
|
Jim: 28`;
|
||||||
|
|
||||||
|
// Helper function to find line number for a specific key in YAML content
|
||||||
|
const findLineNumberForKey = (content: string, key: string): number => {
|
||||||
|
const lines = content.split('\n');
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
if (lines[i].trim().startsWith(`${key}:`)) {
|
||||||
|
return i + 1; // Line numbers are 1-based
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1; // Default to line 1 if not found
|
||||||
|
};
|
||||||
|
|
||||||
// Linting function that validates YAML content
|
// Linting function that validates YAML content
|
||||||
export const validateMetricYaml = (content: string, monaco: any): IMarkerData[] => {
|
export const validateMetricYaml = (
|
||||||
|
content: string,
|
||||||
|
monaco: typeof import('monaco-editor')
|
||||||
|
): IMarkerData[] => {
|
||||||
const markers: IMarkerData[] = [];
|
const markers: IMarkerData[] = [];
|
||||||
let parsed: any;
|
let parsed: any;
|
||||||
|
|
||||||
|
@ -24,12 +37,19 @@ export const validateMetricYaml = (content: string, monaco: any): IMarkerData[]
|
||||||
try {
|
try {
|
||||||
parsed = yaml.load(content);
|
parsed = yaml.load(content);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
// For parse errors, try to extract line information from the error message
|
||||||
|
let lineNumber = 1;
|
||||||
|
const lineMatch = error.message.match(/line (\d+)/i);
|
||||||
|
if (lineMatch && lineMatch[1]) {
|
||||||
|
lineNumber = parseInt(lineMatch[1], 10);
|
||||||
|
}
|
||||||
|
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: 'Invalid YAML 🤣: ' + error.message,
|
message: 'Invalid YAML 🤣: ' + error.message,
|
||||||
startLineNumber: 1,
|
startLineNumber: lineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: lineNumber,
|
||||||
endColumn: 1
|
endColumn: 1
|
||||||
});
|
});
|
||||||
return markers;
|
return markers;
|
||||||
|
@ -55,13 +75,14 @@ export const validateMetricYaml = (content: string, monaco: any): IMarkerData[]
|
||||||
// Check for any unexpected keys
|
// Check for any unexpected keys
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
if (!allowedKeys.includes(key)) {
|
if (!allowedKeys.includes(key)) {
|
||||||
|
const lineNumber = findLineNumberForKey(content, key);
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: `Unexpected key "${key}". Only ${allowedKeys.join(', ')} are allowed.`,
|
message: `Unexpected key "${key}". Only ${allowedKeys.join(', ')} are allowed.`,
|
||||||
startLineNumber: 1,
|
startLineNumber: lineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: lineNumber,
|
||||||
endColumn: 1
|
endColumn: content.split('\n')[lineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -82,39 +103,44 @@ export const validateMetricYaml = (content: string, monaco: any): IMarkerData[]
|
||||||
|
|
||||||
// Validate types for each field
|
// Validate types for each field
|
||||||
if ('Person' in parsed && typeof parsed.Person !== 'string') {
|
if ('Person' in parsed && typeof parsed.Person !== 'string') {
|
||||||
|
const lineNumber = findLineNumberForKey(content, 'Person');
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: 'The "Person" field must be a string.',
|
message: 'The "Person" field must be a string.',
|
||||||
startLineNumber: 1,
|
startLineNumber: lineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: lineNumber,
|
||||||
endColumn: 1
|
endColumn: content.split('\n')[lineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Place' in parsed && typeof parsed.Place !== 'string') {
|
if ('Place' in parsed && typeof parsed.Place !== 'string') {
|
||||||
|
const lineNumber = findLineNumberForKey(content, 'Place');
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: 'The "Place" field must be a string.',
|
message: 'The "Place" field must be a string.',
|
||||||
startLineNumber: 1,
|
startLineNumber: lineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: lineNumber,
|
||||||
endColumn: 1
|
endColumn: content.split('\n')[lineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Age' in parsed && typeof parsed.Age !== 'number') {
|
if ('Age' in parsed && typeof parsed.Age !== 'number') {
|
||||||
|
const lineNumber = findLineNumberForKey(content, 'Age');
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: 'The "Age" field must be a number.',
|
message: 'The "Age" field must be a number.',
|
||||||
startLineNumber: 1,
|
startLineNumber: lineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: lineNumber,
|
||||||
endColumn: 1
|
endColumn: content.split('\n')[lineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Siblings' in parsed) {
|
if ('Siblings' in parsed) {
|
||||||
|
const siblingsLineNumber = findLineNumberForKey(content, 'Siblings');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeof parsed.Siblings !== 'object' ||
|
typeof parsed.Siblings !== 'object' ||
|
||||||
Array.isArray(parsed.Siblings) ||
|
Array.isArray(parsed.Siblings) ||
|
||||||
|
@ -123,22 +149,32 @@ export const validateMetricYaml = (content: string, monaco: any): IMarkerData[]
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: 'The "Siblings" field must be an object with sibling name-age pairs.',
|
message: 'The "Siblings" field must be an object with sibling name-age pairs.',
|
||||||
startLineNumber: 1,
|
startLineNumber: siblingsLineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: siblingsLineNumber,
|
||||||
endColumn: 1
|
endColumn: content.split('\n')[siblingsLineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Validate that each sibling’s age is a number
|
// Validate that each sibling's age is a number
|
||||||
|
const lines = content.split('\n');
|
||||||
Object.entries(parsed.Siblings).forEach(([siblingName, siblingAge]) => {
|
Object.entries(parsed.Siblings).forEach(([siblingName, siblingAge]) => {
|
||||||
if (typeof siblingAge !== 'number') {
|
if (typeof siblingAge !== 'number') {
|
||||||
|
// Look for the sibling in the content
|
||||||
|
let siblingLineNumber = siblingsLineNumber + 1; // Start after Siblings:
|
||||||
|
for (let i = siblingsLineNumber; i < lines.length; i++) {
|
||||||
|
if (lines[i].trim().startsWith(`${siblingName}:`)) {
|
||||||
|
siblingLineNumber = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
markers.push({
|
markers.push({
|
||||||
severity: monaco.MarkerSeverity.Error,
|
severity: monaco.MarkerSeverity.Error,
|
||||||
message: `The age for sibling "${siblingName}" must be a number.`,
|
message: `The age for sibling "${siblingName}" must be a number.`,
|
||||||
startLineNumber: 1,
|
startLineNumber: siblingLineNumber,
|
||||||
startColumn: 1,
|
startColumn: 1,
|
||||||
endLineNumber: 1,
|
endLineNumber: siblingLineNumber,
|
||||||
endColumn: 1
|
endColumn: lines[siblingLineNumber - 1]?.length || 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue