diff --git a/.changeset/weak-bobcats-scream.md b/.changeset/weak-bobcats-scream.md new file mode 100644 index 0000000..f966240 --- /dev/null +++ b/.changeset/weak-bobcats-scream.md @@ -0,0 +1,5 @@ +--- +"codemirror-json-schema": patch +--- + +Handle generic validation error diff --git a/src/index.ts b/src/index.ts index 4648d9c..1d58f33 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,19 @@ -export { jsonCompletion } from "./json-completion.js"; +export { + jsonCompletion, + JSONCompletion, + type JSONCompletionOptions, +} from "./json-completion.js"; export { jsonSchemaLinter, + JSONValidation, type JSONValidationOptions, handleRefresh, } from "./json-validation.js"; export { jsonSchemaHover, + JSONHover, type HoverOptions, type FoundCursorData, type CursorData, diff --git a/src/json-validation.ts b/src/json-validation.ts index f8242c6..bba656c 100644 --- a/src/json-validation.ts +++ b/src/json-validation.ts @@ -4,14 +4,14 @@ import { Draft04, type Draft, type JsonError } from "json-schema-library"; import { getJSONSchema, schemaStateField } from "./state.js"; import { joinWithOr } from "./utils/formatting.js"; -import { JSONMode, JSONPointerData } from "./types.js"; +import { JSONMode, JSONPointerData, RequiredPick } from "./types.js"; import { parseJSONDocumentState } from "./utils/parseJSONDocument.js"; -import { RequiredPick } from "./types.js"; import { el } from "./utils/dom.js"; import { renderMarkdown } from "./utils/markdown.js"; import { MODES } from "./constants.js"; import { parseYAMLDocumentState } from "./utils/parse-yaml-document.js"; import { parseJSON5DocumentState } from "./utils/parseJSON5Document.js"; +import { debug } from "./utils/debug.js"; const getDefaultParser = (mode: JSONMode): typeof parseJSONDocumentState => { switch (mode) { @@ -96,7 +96,7 @@ export class JSONValidation { const errors = errorData?.errors as string[]; if (error.code === "one-of-error" && errors?.length) { return `Expected one of ${joinWithOr( - errors as string[], + errors, (data) => data.data.expected )}`; } @@ -110,6 +110,7 @@ export class JSONValidation { const message = error.message // don't mention root object .replaceAll("in `#` ", "") + .replaceAll("at `#`", "") .replaceAll("/", ".") .replaceAll("#.", ""); return message; @@ -135,9 +136,10 @@ export class JSONValidation { try { errors = this.schema.validate(json.data); } catch {} + debug.log("xxx", "validation errors", errors, json.data); if (!errors.length) return []; // reduce() because we want to filter out errors that don't have a pointer - return errors.reduce((acc, error) => { + return errors.reduce((acc, error) => { const pushRoot = () => { const errorString = this.rewriteError(error); acc.push({ @@ -156,12 +158,11 @@ export class JSONValidation { const errorPath = getErrorPath(error); const pointer = json.pointers.get(errorPath) as JSONPointerData; if ( - error.name === "MaxPropertiesError" ?? + error.name === "MaxPropertiesError" || error.name === "MinPropertiesError" ) { pushRoot(); - } - if (pointer) { + } else if (pointer) { // if the error is a property error, use the key position const isKeyError = positionalErrors.includes(error.name); const errorString = this.rewriteError(error); @@ -182,8 +183,10 @@ export class JSONValidation { source: this.schemaTitle, }); } + } else { + pushRoot(); } return acc; - }, [] as Diagnostic[]); + }, []); } }