From ce31e2ce4fe3b11aa0905f95bf8aeaa43c4b3eb7 Mon Sep 17 00:00:00 2001 From: Rikki Schulte Date: Wed, 29 Nov 2023 11:20:01 +0100 Subject: [PATCH] fix required values --- README.md | 2 +- src/__tests__/json-completion.spec.ts | 54 +----------------------- src/__tests__/json-validation.spec.ts | 12 ++++++ src/json-validation.ts | 18 ++++++-- src/utils/__tests__/jsonPointers.spec.ts | 14 +++++- src/utils/jsonPointers.ts | 10 ++++- 6 files changed, 50 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 5a885a9..fb58295 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Based on whether you want to support json4, json5 or both, you will need to inst ### Breaking Changes: -- 0.5.0 - this breaking change _does not_ effect users using `jsonSchema()` or `json5Schema()` modes, but those using the "custom path". +- 0.5.0 - this breaking change only impacts those following the "custom usage" approach, it _does not_ effect users using the high level, "bundled" `jsonSchema()` or `json5Schema()` modes. See the custom usages below to learn how to use the new `stateExtensions` and `handleRefresh` exports. ### json4 diff --git a/src/__tests__/json-completion.spec.ts b/src/__tests__/json-completion.spec.ts index 4f7a0eb..e3f03ba 100644 --- a/src/__tests__/json-completion.spec.ts +++ b/src/__tests__/json-completion.spec.ts @@ -1,7 +1,6 @@ import { describe, it } from "vitest"; -import { expectCompletion } from "./__helpers__/completion"; -import { testSchema3, testSchema4 } from "./__fixtures__/schemas"; +import { expectCompletion } from "./__helpers__/completion.js"; describe("jsonCompletion", () => { it("should return completion data for simple types", async () => { @@ -292,57 +291,6 @@ describe("jsonCompletion", () => { }, ]); }); - it("should autocomplete for array of objects with filter", async () => { - await expectCompletion('{ "arrayOfObjects": [ { "f|" } ] }', [ - { - detail: "string", - info: "", - label: "foo", - template: '"foo": "#{}"', - type: "property", - }, - ]); - }); - it("should autocomplete for a schema with top level $ref", async () => { - await expectCompletion( - '{ "| }', - [ - { - type: "property", - detail: "string", - info: "", - label: "foo", - }, - { - type: "property", - detail: "number", - info: "", - label: "bar", - }, - ], - { schema: testSchema3 } - ); - }); - it("should autocomplete for a schema with top level complex type", async () => { - await expectCompletion( - '{ "| }', - [ - { - type: "property", - detail: "string", - info: "", - label: "foo", - }, - { - type: "property", - detail: "number", - info: "", - label: "bar", - }, - ], - { schema: testSchema4 } - ); - }); }); describe("json5Completion", () => { diff --git a/src/__tests__/json-validation.spec.ts b/src/__tests__/json-validation.spec.ts index 4f0cf4d..0695ce7 100644 --- a/src/__tests__/json-validation.spec.ts +++ b/src/__tests__/json-validation.spec.ts @@ -53,10 +53,21 @@ describe("json-validation", () => { [[32, 37, "Additional property `bar` in `#` is not allowed"]] ); }); + it("should provide formatted error message when required fields are missing", () => { + expectErrors( + `{ + "foo": "example", + "object": { "foo": "true" } + }`, + [[43, 46, "Expected property `foo` in `#/object`"]], + testSchema2 + ); + }); it("should provide formatted error message for oneOf fields with more than 2 items", () => { expectErrors( `{ "foo": "example", + "object": { "foo": "true" }, "oneOfEg": 123 }`, [[43, 46, 'Expected one of `"string"`, `"array"`, or `"boolean"`']], @@ -67,6 +78,7 @@ describe("json-validation", () => { expectErrors( `{ "foo": "example", + "object": { "foo": "true" }, "oneOfEg2": 123 }`, [[44, 47, 'Expected one of `"string"` or `"array"`']], diff --git a/src/json-validation.ts b/src/json-validation.ts index cf5b746..9ae1105 100644 --- a/src/json-validation.ts +++ b/src/json-validation.ts @@ -106,7 +106,7 @@ export class JSONValidation { try { errors = this.schema.validate(json.data); } catch {} - + console.log(Array.from(json.pointers.keys())); if (!errors.length) return []; // reduce() because we want to filter out errors that don't have a pointer return errors.reduce((acc, error) => { @@ -114,16 +114,26 @@ export class JSONValidation { const pointer = json.pointers.get(errorPath) as JSONPointerData; if (pointer) { // if the error is a property error, use the key position - const isPropertyError = error.name === "NoAdditionalPropertiesError"; + const isKeyError = + error.name === "NoAdditionalPropertiesError" || + error.name === "RequiredPropertyError"; acc.push({ - from: isPropertyError ? pointer.keyFrom : pointer.valueFrom, - to: isPropertyError ? pointer.keyTo : pointer.valueTo, + from: isKeyError ? pointer.keyFrom : pointer.valueFrom, + to: isKeyError ? pointer.keyTo : pointer.valueTo, // TODO: create a domnode and replace `` with // renderMessage: () => error.message, message: this.rewriteError(error), severity: "error", source: this.schemaTitle, }); + } else { + acc.push({ + from: 0, + to: 0, + message: this.rewriteError(error), + severity: "error", + source: this.schemaTitle, + }); } return acc; }, [] as Diagnostic[]); diff --git a/src/utils/__tests__/jsonPointers.spec.ts b/src/utils/__tests__/jsonPointers.spec.ts index 83ba11d..aada790 100644 --- a/src/utils/__tests__/jsonPointers.spec.ts +++ b/src/utils/__tests__/jsonPointers.spec.ts @@ -63,7 +63,7 @@ describe("jsonPointerForPosition for json5", () => { describe("getJsonPointers", () => { it("should return a map of all pointers for a document", () => { const state = EditorState.create({ - doc: '{"object": { "foo": true }, "bar": 123}', + doc: '{"object": { "foo": true }, "bar": 123, "baz": [1,2,3]}', extensions: [json()], }); const pointers = getJsonPointers(state); @@ -79,6 +79,18 @@ describe("getJsonPointers", () => { valueFrom: 35, valueTo: 38, }); + expect(pointers.get("/baz")).toEqual({ + keyFrom: 40, + keyTo: 45, + valueFrom: 47, + valueTo: 54, + }); + expect(pointers.get("/baz/0")).toEqual({ + keyFrom: 40, + keyTo: 45, + valueFrom: 47, + valueTo: 55, + }); }); }); diff --git a/src/utils/jsonPointers.ts b/src/utils/jsonPointers.ts index f611b98..d7c1072 100644 --- a/src/utils/jsonPointers.ts +++ b/src/utils/jsonPointers.ts @@ -61,7 +61,15 @@ export const getJsonPointers = ( const pointers: JSONPointersMap = new Map(); json.iterate({ enter: (type: SyntaxNodeRef) => { - if (type.name === "PropertyName") { + if ( + type.name === "PropertyName" || + type.name === "Object" + // type.name === "Number" || + // type.name === "String" || + // type.name === "Boolean" || + // type.name === "Null" || + // type.name === "Array" + ) { const pointer = getJsonPointerAt(state.doc, type.node); const { from: keyFrom, to: keyTo } = type.node;