fix(typebox): migrate to v1 with extension compat (#3474)
* fix(typebox): migrate to v1 with extension compat Replace AJV-based validation with TypeBox-native validation, keep legacy extension imports working (including @sinclair/typebox/compiler), and restore coercion for serialized/plain JSON schemas. This change closes #3112. * fix(typebox): use canonical imports and harden coercion Switch first-party code to canonical typebox imports while retaining legacy extension aliases in the loader. Remove obsolete runtime codegen guards, expand serialized JSON-schema coercion coverage, and update related tests and fixtures. Fixes #3112. --------- Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { EditorTheme, MarkdownTheme, SelectListTheme } from "@mariozechner/pi-tui";
|
||||
import { type Static, Type } from "@sinclair/typebox";
|
||||
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
||||
import chalk from "chalk";
|
||||
import { highlight, supportsLanguage } from "cli-highlight";
|
||||
import { type Static, Type } from "typebox";
|
||||
import { Compile } from "typebox/compile";
|
||||
import { getCustomThemesDir, getThemesDir } from "../../../config.js";
|
||||
import type { SourceInfo } from "../../../core/source-info.js";
|
||||
|
||||
@@ -94,7 +94,7 @@ const ThemeJsonSchema = Type.Object({
|
||||
|
||||
type ThemeJson = Static<typeof ThemeJsonSchema>;
|
||||
|
||||
const validateThemeJson = TypeCompiler.Compile(ThemeJsonSchema);
|
||||
const validateThemeJson = Compile(ThemeJsonSchema);
|
||||
|
||||
export type ThemeColor =
|
||||
| "accent"
|
||||
@@ -515,23 +515,29 @@ export function getAvailableThemesWithPaths(): ThemeInfo[] {
|
||||
function parseThemeJson(label: string, json: unknown): ThemeJson {
|
||||
if (!validateThemeJson.Check(json)) {
|
||||
const errors = Array.from(validateThemeJson.Errors(json));
|
||||
const missingColors: string[] = [];
|
||||
const missingColors = new Set<string>();
|
||||
const otherErrors: string[] = [];
|
||||
|
||||
for (const e of errors) {
|
||||
// Check for missing required color properties
|
||||
const match = e.path.match(/^\/colors\/(\w+)$/);
|
||||
if (match && e.message.includes("Required")) {
|
||||
missingColors.push(match[1]);
|
||||
} else {
|
||||
otherErrors.push(` - ${e.path}: ${e.message}`);
|
||||
for (const error of errors) {
|
||||
if (error.keyword === "required" && error.instancePath === "/colors") {
|
||||
const requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;
|
||||
for (const requiredProperty of requiredProperties ?? []) {
|
||||
missingColors.add(requiredProperty);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const path = error.instancePath || "/";
|
||||
otherErrors.push(` - ${path}: ${error.message}`);
|
||||
}
|
||||
|
||||
let errorMessage = `Invalid theme "${label}":\n`;
|
||||
if (missingColors.length > 0) {
|
||||
if (missingColors.size > 0) {
|
||||
errorMessage += "\nMissing required color tokens:\n";
|
||||
errorMessage += missingColors.map((c) => ` - ${c}`).join("\n");
|
||||
errorMessage += Array.from(missingColors)
|
||||
.sort()
|
||||
.map((color) => ` - ${color}`)
|
||||
.join("\n");
|
||||
errorMessage += '\n\nPlease add these colors to your theme\'s "colors" object.';
|
||||
errorMessage += "\nSee the built-in themes (dark.json, light.json) for reference values.";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user