Skip to main content
Glama
validate.ts2.97 kB
interface ValidationResult { valid: boolean; errors: string[]; warnings: string[]; spec: Record<string, unknown>; } /** * Validate a Vega-Lite specification * This is a basic validation - for production, consider using the official vega-lite validator */ export async function validateSpec( spec: Record<string, unknown> ): Promise<ValidationResult> { const errors: string[] = []; const warnings: string[] = []; // Check required top-level properties if (!spec.$schema) { errors.push("Missing required property: $schema"); } if (!spec.mark && !spec.layer && !spec.hconcat && !spec.vconcat && !spec.concat) { errors.push("Missing required property: must have one of 'mark', 'layer', 'hconcat', 'vconcat', or 'concat'"); } if (!spec.data) { warnings.push("No data specified - spec may not render without data"); } // Check mark type if present if (spec.mark) { const validMarks = [ "arc", "area", "bar", "circle", "geoshape", "image", "line", "point", "rect", "rule", "square", "text", "tick", "trail", ]; const markType = typeof spec.mark === "string" ? spec.mark : (spec.mark as any)?.type; if (markType && !validMarks.includes(markType)) { errors.push(`Invalid mark type: '${markType}'. Valid types are: ${validMarks.join(", ")}`); } } // Check encoding channels if (spec.encoding) { const encoding = spec.encoding as Record<string, unknown>; const validChannels = [ "x", "y", "x2", "y2", "color", "fill", "stroke", "opacity", "fillOpacity", "strokeOpacity", "size", "shape", "angle", "radius", "theta", "text", "tooltip", "href", "url", "row", "column", "facet", "detail", "key", "order", ]; for (const channel of Object.keys(encoding)) { if (!validChannels.includes(channel)) { warnings.push(`Unknown encoding channel: '${channel}'`); } } } // Check data types in encoding if (spec.encoding) { const encoding = spec.encoding as Record<string, any>; const validTypes = ["quantitative", "temporal", "nominal", "ordinal", "geojson"]; for (const [channel, def] of Object.entries(encoding)) { if (def.type && !validTypes.includes(def.type)) { errors.push(`Invalid type '${def.type}' in encoding channel '${channel}'. Valid types are: ${validTypes.join(", ")}`); } if (!def.field && !def.value && !def.datum && channel !== "detail" && channel !== "order") { warnings.push(`Encoding channel '${channel}' has no field, value, or datum specified`); } } } // Check schema version if (spec.$schema && typeof spec.$schema === "string") { if (!spec.$schema.includes("vega-lite")) { errors.push("Schema URL should point to a vega-lite schema"); } } return { valid: errors.length === 0, errors, warnings, spec, }; }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/inteligencianegociosmmx/vegaLite_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server