-
-
Notifications
You must be signed in to change notification settings - Fork 4
Readme #53
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
Readme #53
Changes from 3 commits
c734b7a
2792ad9
f0154de
721b561
cb725ad
aff5e52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| node_modules/ | ||
|
|
||
| docs/ | ||
|
|
||
|
|
||
| scratch/ | ||
| TODO* | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,22 +1,128 @@ | ||||||
| # Hyperjump - Better JSON Schema Errors | ||||||
| # Hyperjump - Better JSON Schema Errors | ||||||
| It transforms standard, machine-oriented validation output into clear, human-friendly error messages ideal for API responses and developer tools. Built upon the official JSON Schema Output Format introduced in draft 2019-09, it ensures seamless compatibility with any compliant validator. | ||||||
|
|
||||||
| TODO: Write a short description of the package | ||||||
| ### Node.js | ||||||
|
|
||||||
| ```bash | ||||||
| npm install @hyperjump/better-json-schema-errors | ||||||
| ``` | ||||||
|
|
||||||
| ## API Error Message Format | ||||||
|
|
||||||
| Our API Error Format includes :- | ||||||
| - **`schemaLocation`** - A JSON URI that points to the specific keyword(s) within the schema that failed validation. This can be a single string or an array of absolute keyword locations for errors that are grouped together. | ||||||
|
||||||
|
|
||||||
| - **`instanceLocation`** - JSON Pointer to the invalid piece of input data. | ||||||
|
|
||||||
| - **`message`** - Human-friendly explanation of the validation error. | ||||||
|
|
||||||
| Example:- | ||||||
| ```json | ||||||
| { | ||||||
| "errors": [ | ||||||
| { | ||||||
| "schemaLocation": "https://example.com/main#/properties/name/minLength", | ||||||
| "instanceLocation": "#/name", | ||||||
| "message": "Expected a string at least 5 characters long." | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ## Install | ||||||
|
|
||||||
| This module is designed for node.js (ES Modules, TypeScript) and browsers. It | ||||||
| should work in Bun and Deno as well, but the test runner doesn't work in these | ||||||
| environments, so this module may be less stable in those environments. | ||||||
|
|
||||||
| ### Node.js | ||||||
|
|
||||||
| ```bash | ||||||
| npm install @hyperjump/better-json-schema-errors | ||||||
|
|
||||||
| ## Examples and Basic Usage | ||||||
| Better JSON Schema Errors works with **any JSON Schema validator** that follows the official [JSON Schema Output Format](https://json-schema.org/draft/2020-12/json-schema-core#name-output-structure). | ||||||
| In this example, we’ll showcase it with the [Hyperjump JSON Schema Validator](https://github.com/hyperjump-io/json-schema). | ||||||
|
|
||||||
| Now let's define a schema and some invalid data, then run the validation and process the output with `better-json-schema-errors`. :- | ||||||
| ```js | ||||||
| import { registerSchema, validate, unregisterSchema } from "@hyperjump/json-schema/draft-2020-12"; | ||||||
| import { betterJsonSchemaErrors } from "@hyperjump/better-json-schema-errors"; | ||||||
|
|
||||||
| const schemaUri = "https://example.com/main"; | ||||||
| registerSchema({ | ||||||
| $schema: "https://json-schema.org/draft/2020-12/schema", | ||||||
| anyOf: [ | ||||||
| { enum: ["a", "b", "c"] } | ||||||
| ] | ||||||
| }, schemaUri); | ||||||
|
|
||||||
| const instance = 4; | ||||||
| const result = await validate(schemaUri, instance, "BASIC"); | ||||||
|
|
||||||
| if (result.valid) { | ||||||
| console.log("Valid instance!"); | ||||||
| } else { | ||||||
| const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance); | ||||||
| console.log(JSON.stringify(friendlyErrors, null, 2)); | ||||||
| } | ||||||
|
|
||||||
| unregisterSchema(schemaUri); | ||||||
|
|
||||||
| ``` | ||||||
| Output:- | ||||||
| ```json | ||||||
| { | ||||||
| "errors": [ | ||||||
| { | ||||||
| "message": "Unexpected value 4. Expected one of: 'a', 'b', or 'c'.", | ||||||
| "instanceLocation": "#", | ||||||
| "schemaLocation": "https://example.com/main#/enum" | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ## Examples and Usage | ||||||
| ## Features and Advanced Usage | ||||||
|
|
||||||
| ### 1. Works with All Output Formats | ||||||
| Supports all three standardized output formats: | ||||||
| - **BASIC** — The "Basic" structure is a flat list of output units | ||||||
| - **DETAILED** — The "Detailed" structure is based on the schema and can be more readable for both | ||||||
| humans and machines. | ||||||
| - **VERBOSE** — The "Verbose" structure is a fully realised hierarchy that exactly matches that of the | ||||||
| schema. | ||||||
|
|
||||||
| No matter which output format your validator produces, Better JSON Schema Errors can process it. | ||||||
|
|
||||||
| ### 2. Multiple Schema Locations | ||||||
| Sometimes a single validation issue is tied to **more than one schema keyword**. | ||||||
| For example, when both `minimum` and `exclusiveMinimum` apply, or when `minLength` and `maxLength` constraints overlap or when when both `minimum` and `maximum` apply. | ||||||
|
|
||||||
| Instead of generating duplicate error messages, It groups these into an **array of schema locations** and produces one concise, human-friendly message :- | ||||||
|
||||||
| Instead of generating duplicate error messages, It groups these into an **array of schema locations** and produces one concise, human-friendly message :- | |
| Instead of multiple related error messages, It groups these into an **array of schema locations** and produces one concise, human-friendly message :- |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| The library uses [fluent](https://projectfluent.org) `.ftl` files provide localized error messages. By default, only English is supported. | |
| The library uses [fluent](https://projectfluent.org) `.ftl` files to provide localized error messages. By default, only English is supported. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have several keywords with their own documentation file and I don't want to list each one of them individually. We should be able to describe some of the general strategies we use in the README and then link to the documentation directory as a whole for people to look through the individual documentation files.
I think here in the README we should talk about our general strategy of trying to determine which alternative the user intended and only showing those messages. Then the individual documentation can describe how we determine which alternative to choose.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| ## Handling `anyOf` with Clarity | ||
|
|
||
| **Better JSON Schema Errors** intelligently simplifies error output, providing clear, consolidated error messages that are easier to debug. | ||
| Here are the differnt cases and how better-json-schema-errors handles them to produces better errors. | ||
|
|
||
| --- | ||
|
|
||
| #### 1. Mismatched Types | ||
|
|
||
| If the instance's type doesn't match any of the alternatives in an `anyOf`, the library provides a concise error message listing the expected types. | ||
|
|
||
| **Schema:** | ||
| ```json | ||
| { | ||
| "anyOf": [ | ||
| { "type": "string" }, | ||
| { "type": "number" } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Invalid Instance:- | ||
| ``` Json | ||
| false | ||
| ``` | ||
| BetterJSONSchemaErrors Output:- | ||
| ``` Json | ||
| { | ||
| "errors": [ | ||
| { | ||
| "schemaLocation": "https://example.com/main#/anyOf", | ||
| "instanceLocation": "#", | ||
| "message": "The instance should be of type 'string' or 'number' but found 'boolean'." | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| ``` | ||
| #### 2. Partial Match with a Failed Constraint | ||
|
|
||
| If the instance's type matches one of the `anyOf` alternatives but fails a subsequent constraint (like `minLength`), our library correctly identifies the specific rule that was violated. | ||
|
|
||
| **Schema:** | ||
| ```json | ||
| { | ||
| "anyOf": [ | ||
| { "type": "string", "minLength": 5 }, | ||
| { "type": "number" } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Invalid Instance:- | ||
| ``` Json | ||
| "abc" | ||
| ``` | ||
| BetterJSONSchemaErrors Output:- | ||
| ``` Json | ||
| { | ||
| "errors": [ | ||
| { | ||
| "schemaLocation": "https://example.com/main#/anyOf/0/minLength", | ||
| "instanceLocation": "#", | ||
| "message": "Expected a string at least 5 characters long." | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| #### 3. Multiple types match, pick based on field overlap | ||
|
|
||
| When an instance matches multiple `anyOf` alternatives type, the library prioritizes the one with the most relevant error based on the instance's fields. | ||
|
|
||
| **Schema:** | ||
| ```json | ||
| { | ||
| "anyOf": [ | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "name": { "type": "string" }, | ||
| "age": { "type": "number" } | ||
| }, | ||
| "required": ["name", "age"] | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "title": { "type": "string" }, | ||
| "author": { "type": "string" }, | ||
| "ID": { "type": "string", "pattern": "^[0-9\\-]+$" } | ||
| }, | ||
| "required": ["title", "author", "ID"] | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Invalid Instance:- | ||
| ``` Json | ||
| { | ||
| "title": "Clean Code", | ||
| "author": "Robert Martin", | ||
| "ID": "NotValidId" | ||
| } | ||
| ``` | ||
| BetterJSONSchemaErrors Output:- | ||
| ``` Json | ||
| { | ||
| "errors": [ | ||
| { | ||
| "schemaLocation": "https://example.com/main#/anyOf/1/properties/ID/pattern", | ||
| "instanceLocation": "#/ID", | ||
| "message": "The instance should match the format: \"^[0-9\\-]+$\". " | ||
| } | ||
| ] | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, we can't put it in the
docsfolder because that's where typedoc generates its thing for the website. You'll need to come up with a different name. Maybe justdocumentation.