Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade json schema lib, replace backticks with code blocks, no value context bug #64

Merged
merged 6 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/nasty-islands-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"codemirror-json-schema": minor
---

**Breaking Change**: replaces backticks with `<code>` blocks in hover and completion! This just seemed to make more sense.

- upgrade `json-schema-library` to the latest 8.x with patch fixes, remove "forked" pointer step logic
- after autocompleting a property, when there is empty value, provide full autocomplete options
- as noted in the breaking change notice, all psuedo-markdown backtick ``delimiters are replaced with`<code>`
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ dist
cjs
/public
coverage
cjs
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

### Minor Changes

- [#63](https://github.com/acao/codemirror-json-schema/pull/63) [`a73c517`](https://github.com/acao/codemirror-json-schema/commit/a73c517722bbe9d37124993117c091e259eb6998) Thanks [@acao](https://github.com/acao)! - **breaking change**: only impacts those following the "custom usage" approach, it _does not_ effect users using the high level, "bundled" `jsonSchema()` or `json5Schema()` modes.
- [#63](https://github.com/acao/codemirror-json-schema/pull/63) [`a73c517`](https://github.com/acao/codemirror-json-schema/commit/a73c517722bbe9d37124993117c091e259eb6998) Thanks [@acao](https://github.com/acao)!

- **breaking change**: only impacts those following the "custom usage" approach, it _does not_ effect users using the high level, "bundled" `jsonSchema()` or `json5Schema()` modes.

Previously, we ask you to pass schema to each of the linter, completion and hover extensions.

Expand Down Expand Up @@ -49,6 +51,8 @@
];
```

- upgrade to use full `.js` import paths for `NodeNext` compatibility, however not all of our dependencies are compatible with this mode, thus we continue using the legacy `nodeResolution` strategy.

## 0.4.5

### Patch Changes
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@types/json-schema": "^7.0.12",
"@types/node": "^20.4.2",
"json-schema": "^0.4.0",
"json-schema-library": "^8.0.0"
"json-schema-library": "^9.1.2"
},
"optionalDependencies": {
"@codemirror/lang-json": "^6.0.1",
Expand All @@ -73,17 +73,17 @@
"devDependencies": {
"@changesets/cli": "^2.26.2",
"@codemirror/autocomplete": "^6.8.1",
"@codemirror/basic-setup": "^0.20.0",
"@codemirror/commands": "^6.2.4",
"@codemirror/theme-one-dark": "^6.1.2",
"@evilmartians/lefthook": "^1.4.6",
"@vitest/coverage-v8": "^0.34.6",
"codemirror": "^6.0.1",
"@codemirror/language": "^6.8.0",
"@codemirror/lint": "^6.4.0",
"@codemirror/state": "^6.2.1",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.14.1",
"@codemirror/basic-setup": "^0.20.0",
"@evilmartians/lefthook": "^1.4.6",
"@lezer/common": "^1.0.3",
"@vitest/coverage-v8": "^0.34.6",
"codemirror": "^6.0.1",
"codemirror-json5": "^1.0.3",
"happy-dom": "^10.3.2",
"json5": "^2.2.3",
Expand Down
55 changes: 51 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/__tests__/json-hover.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ describe("JSONHover#getHoverTexts", () => {
);
expect(hoverTexts).toEqual({
message: "an example oneOf",
typeInfo: "oneOf: `string`, `array`, or `boolean`",
typeInfo:
"oneOf: <code>string</code>, <code>array</code>, or <code>boolean</code>",
});
});
it("should provide oneOf texts with valid values", async () => {
Expand All @@ -86,7 +87,8 @@ describe("JSONHover#getHoverTexts", () => {
);
expect(hoverTexts).toEqual({
message: "an example oneOf",
typeInfo: "oneOf: `string`, `array`, or `boolean`",
typeInfo:
"oneOf: <code>string</code>, <code>array</code>, or <code>boolean</code>",
});
});
});
Expand Down
48 changes: 34 additions & 14 deletions src/__tests__/json-validation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,52 @@ const getErrors = (jsonString: string, schema?: JSONSchema7) => {
});
return new JSONValidation().doValidation(view);
};

const common = {
severity: "error" as Diagnostic["severity"],
source: "json-schema",
};

const expectErrors = (
jsonString: string,
errors: [from: number | undefined, to: number | undefined, message: string][],
schema?: JSONSchema7
) => {
expect(getErrors(jsonString, schema)).toEqual(
const filteredErrors = getErrors(jsonString, schema).map(
({ renderMessage, ...error }) => error
);
expect(filteredErrors).toEqual(
errors.map(([from, to, message]) => ({ ...common, from, to, message }))
);
};

const common = {
severity: "error" as Diagnostic["severity"],
source: "json-schema",
};

describe("json-validation", () => {
it("should provide range for a value error", () => {
expectErrors('{"foo": 123}', [
[8, 11, "Expected `string` but received `number`"],
[8, 11, "Expected <code>string</code> but received <code>number</code>"],
]);
});
it("should provide range for an unknown key error", () => {
expectErrors('{"foo": "example", "bar": 123}', [
[19, 24, "Additional property `bar` in `#` is not allowed"],
[19, 24, "Additional property <code>bar</code> is not allowed"],
]);
});
it("should not handle invalid json", () => {
expectErrors('{"foo": "example" "bar": 123}', [
[undefined, undefined, "Expected `object` but received `null`"],
[
undefined,
undefined,
"Expected <code>object</code> but received <code>null</code>",
],
]);
});
it("should provide range for invalid multline json", () => {
it("should provide range for invalid multiline json", () => {
expectErrors(
`{
"foo": "example",
"bar": "something else"
}`,
[[32, 37, "Additional property `bar` in `#` is not allowed"]]
[[32, 37, "Additional property <code>bar</code> is not allowed"]]
);
});
it("should provide formatted error message when required fields are missing", () => {
Expand All @@ -61,7 +69,13 @@ describe("json-validation", () => {
"foo": "example",
"object": {}
}`,
[[46, 48, "The required property `foo` is missing at `object`"]],
[
[
46,
48,
"The required property <code>foo</code> is missing at <code>object</code>",
],
],
testSchema2
);
});
Expand All @@ -72,7 +86,13 @@ describe("json-validation", () => {
"object": { "foo": "true" },
"oneOfEg": 123
}`,
[[80, 83, 'Expected one of `"string"`, `"array"`, or `"boolean"`']],
[
[
80,
83,
"Expected one of <code>string</code>, <code>array</code>, or <code>boolean</code>",
],
],
testSchema2
);
});
Expand All @@ -83,7 +103,7 @@ describe("json-validation", () => {
"object": { "foo": "true" },
"oneOfEg2": 123
}`,
[[81, 84, 'Expected one of `"string"` or `"array"`']],
[[81, 84, "Expected one of <code>string</code> or <code>array</code>"]],
testSchema2
);
});
Expand Down
19 changes: 8 additions & 11 deletions src/json-completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ import {
stripSurroundingQuotes,
getNodeAtPosition,
} from "./utils/node.js";
import { Draft07, JsonError } from "json-schema-library";
import { getJSONSchema } from "./state.js";
import { Draft07, isJsonError } from "json-schema-library";
import { jsonPointerForPosition } from "./utils/jsonPointers.js";
import { TOKENS } from "./constants.js";
import { getJSONSchema } from "./state.js";
import getSchema from "./utils/schema-lib/getSchema.js";

function json5PropertyInsertSnippet(rawWord: string, value: string) {
if (rawWord.startsWith('"')) {
Expand Down Expand Up @@ -688,7 +687,10 @@ export class JSONCompletion {
): JSONSchema7Definition[] {
const draft = new Draft07(this.schema!);
let pointer = jsonPointerForPosition(ctx.state, ctx.pos);
let subSchema = getSchema(draft, pointer);
let subSchema = draft.getSchema({ pointer });
if (isJsonError(subSchema)) {
subSchema = subSchema.data?.schema;
}
// if we don't have a schema for the current pointer, try the parent pointer
if (
!subSchema ||
Expand All @@ -697,7 +699,7 @@ export class JSONCompletion {
subSchema.type === "undefined"
) {
pointer = pointer.replace(/\/[^/]*$/, "/");
subSchema = getSchema(draft, pointer);
subSchema = draft.getSchema({ pointer });
}

debug.log("xxx", "pointer..", JSON.stringify(pointer));
Expand All @@ -708,8 +710,7 @@ export class JSONCompletion {
}
// const subSchema = new Draft07(this.schema).getSchema(pointer);
debug.log("xxx", "subSchema..", subSchema);

if (this.isJsonError(subSchema)) {
if (!subSchema) {
return [];
}

Expand All @@ -735,10 +736,6 @@ export class JSONCompletion {
return [subSchema as JSONSchema7];
}

isJsonError(d: JSONSchema7 | JsonError): d is JsonError {
return d.type === "error";
}

private expandSchemaProperty(
property: JSONSchema7Definition,
schema: JSONSchema7
Expand Down
Loading