Skip to content

Commit 947cd5d

Browse files
authored
Merge pull request #53 from arpitkuriyal/readme
Readme
2 parents 0476c26 + aff5e52 commit 947cd5d

File tree

6 files changed

+659
-10
lines changed

6 files changed

+659
-10
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node_modules/
22

3-
docs/
3+
/docs
44

55
scratch/
66
TODO*

README.md

Lines changed: 259 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,275 @@
1-
# Hyperjump - Better JSON Schema Errors
1+
# Hyperjump - Better JSON Schema Errors
2+
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.
23

3-
TODO: Write a short description of the package
4+
### Node.js
5+
6+
```bash
7+
npm install @hyperjump/better-json-schema-errors
8+
```
9+
10+
## API Error Message Format
11+
12+
Our API Error Format includes :-
13+
- **`schemaLocation`** - A 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.
14+
15+
- **`instanceLocation`** - JSON Pointer to the invalid piece of input data.
16+
17+
- **`message`** - Human-friendly explanation of the validation error.
18+
19+
Example:-
20+
```json
21+
{
22+
"errors": [
23+
{
24+
"schemaLocation": "https://example.com/main#/properties/name/minLength",
25+
"instanceLocation": "#/name",
26+
"message": "Expected a string at least 5 characters long."
27+
}
28+
]
29+
}
30+
```
431

532
## Install
633

734
This module is designed for node.js (ES Modules, TypeScript) and browsers. It
835
should work in Bun and Deno as well, but the test runner doesn't work in these
936
environments, so this module may be less stable in those environments.
1037

11-
### Node.js
38+
## Examples and Basic Usage
39+
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).
40+
In this example, we’ll showcase it with the [Hyperjump JSON Schema Validator](https://github.com/hyperjump-io/json-schema).
1241

13-
```bash
14-
npm install @hyperjump/better-json-schema-errors
42+
Now let's define a schema and some invalid data, then run the validation and process the output with `better-json-schema-errors`. :-
43+
```js
44+
import { registerSchema, validate, unregisterSchema } from "@hyperjump/json-schema/draft-2020-12";
45+
import { betterJsonSchemaErrors } from "@hyperjump/better-json-schema-errors";
46+
47+
const schemaUri = "https://example.com/main";
48+
registerSchema({
49+
$schema: "https://json-schema.org/draft/2020-12/schema",
50+
anyOf: [
51+
{ enum: ["a", "b", "c"] }
52+
]
53+
}, schemaUri);
54+
55+
const instance = 4;
56+
const result = await validate(schemaUri, instance, "BASIC");
57+
58+
if (result.valid) {
59+
console.log("Valid instance!");
60+
} else {
61+
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance);
62+
console.log(JSON.stringify(friendlyErrors, null, 2));
63+
}
64+
65+
unregisterSchema(schemaUri);
66+
67+
```
68+
Output:-
69+
```json
70+
{
71+
"errors": [
72+
{
73+
"message": "Unexpected value 4. Expected one of: 'a', 'b', or 'c'.",
74+
"instanceLocation": "#",
75+
"schemaLocation": "https://example.com/main#/enum"
76+
}
77+
]
78+
}
79+
```
80+
81+
## Features and Advanced Usage
82+
83+
### 1. Works with All Output Formats
84+
Supports all three standardized output formats:
85+
- **BASIC** — The "Basic" structure is a flat list of output units
86+
- **DETAILED** — The "Detailed" structure is based on the schema and can be more readable for both
87+
humans and machines.
88+
- **VERBOSE** — The "Verbose" structure is a fully realised hierarchy that exactly matches that of the
89+
schema.
90+
91+
No matter which output format your validator produces, Better JSON Schema Errors can process it.
92+
93+
### 2. Multiple Schema Locations
94+
Sometimes a single validation issue is tied to **more than one schema keyword**.
95+
For example, when both `minimum` and `exclusiveMinimum` apply, or when `minLength` and `maxLength` constraints overlap or when when both `minimum` and `maximum` apply.
96+
97+
Instead of multiple related error messages, It groups these into an **array of schema locations** and produces one concise, human-friendly message :-
98+
99+
```json
100+
{
101+
"schemaLocation": [
102+
"https://example.com/main#/minimum",
103+
"https://example.com/main#/maximum"
104+
],
105+
"instanceLocation": "#/age",
106+
"message": "Expected a number greater than 5 and less than 10."
107+
}
15108
```
109+
### 3. Localization
16110

17-
## Examples and Usage
111+
The library uses [fluent](https://projectfluent.org) `.ftl` files to provide localized error messages. By default, only English is supported.
18112

19-
TODO: Write some examples
113+
We need contributions from different countries to add more languages.
20114

115+
To change the language, pass a language option to the betterJsonSchemaErrors function, like this:
116+
117+
```js
118+
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance, { language: "en-US" });
119+
```
120+
121+
### 4. Handling `anyOf`/`oneOf` with Clarity
122+
123+
The `anyOf`/`oneOf` keyword is a powerful but complex JSON Schema feature. **better-json-schema-errors** intelligently simplifies its output by providing clear, consolidated error messages that are easier to debug. Whenever possible it will try to determine which alternative the user intended and focus the error output to only those errors related to correcting the data for that alternative.
124+
125+
**Schema:**
126+
```json
127+
{
128+
"anyOf": [
129+
{ "type": "string", "minLength": 5 },
130+
{ "type": "number" }
131+
]
132+
}
133+
```
134+
135+
Invalid Instance:-
136+
```json
137+
"abc"
138+
```
139+
BetterJSONSchemaErrors Output:-
140+
```json
141+
{
142+
"errors": [
143+
{
144+
"schemaLocation": "https://example.com/main#/anyOf/0/minLength",
145+
"instanceLocation": "#",
146+
"message": "Expected a string at least 5 characters long."
147+
}
148+
]
149+
}
150+
```
151+
152+
For detailed examples, see the dedicated [**anyOf** documentation](./documentation/anyOf.md).
153+
154+
### 5. Handling `enum` with Suggestions
155+
156+
When data doesn’t match an allowed `enum` value, Better JSON Schema Errors produces clear messages.
157+
It can also suggest the closest valid value (using string similarity).
158+
159+
Example:
160+
161+
```json
162+
{
163+
"errors": [
164+
{
165+
"message": "Unexpected value 'appl'. Did you mean 'apple'?",
166+
"instanceLocation": "#/fruit",
167+
"schemaLocation": "https://example.com/main#/properties/fruit/enum"
168+
}
169+
]
170+
}
171+
```
172+
This makes typos or near-misses much easier to debug.
173+
For full details and strategies, see the dedicated [enum documentation](./documentation/enum.md).
174+
175+
### 6. Range constraint keywords
176+
Better JSON Schema Errors consolidates multiple range-related validation errors (`minimum`, `maxLength`, `minItems`, etc.) into a single, clear message.
177+
For example, a schema like:
178+
```json
179+
{ "allOf": [
180+
{ "minimum": 3 },
181+
{ "minimum": 5 }
182+
]
183+
}
184+
```
185+
Instance:-
186+
```json
187+
2
188+
```
189+
BetterJSONSchemaErrors Output:-
190+
```json
191+
{
192+
"errors": [
193+
{
194+
"schemaLocation": "https://example.com/main#/allOf/1/minimum",
195+
"instanceLocation": "#",
196+
"message": "Expected a number greater than 5."
197+
}
198+
]
199+
}
200+
```
201+
Instead of 2 error message it manages to give a single concise error message. For details, see the dedicated [Range documenetation](./documentation/range-handler.md)
202+
203+
### 6. Custom Keywords and Error Handlers
204+
In order to create the custom keywords and error handlers we need to create and
205+
register two types of handlers: **Normalization Handler** and **Error Handlers**.
206+
207+
1. Normalization: This phase takes the raw, often deeply nested, error output
208+
from the validator and converts it into a NormalizedOutput (you can check type of
209+
normalizedOutput in the index.d.ts file).
210+
211+
2. Error Handling: This phase takes the normalized output and uses it to generate the final error messages. This is the job of the Error Handlers.
212+
213+
Fist step -: Creating the keywordHandler
214+
```js
215+
/**
216+
* @import { KeywordHandler } from "@hyperjump/better-json-schema-errors"
217+
*/
218+
219+
/** @type KeywordHandler */
220+
const multipleOfTen = {
221+
appliesTo(type) {
222+
return type === "number"
223+
}
224+
};
225+
226+
export default multipleOfTen;
227+
228+
```
229+
230+
Second step -: Creating the errorHandler
231+
```js
232+
import { getSchema } from "@hyperjump/json-schema/experimental";
233+
import * as Schema from "@hyperjump/browser";
234+
import * as Instance from "@hyperjump/json-schema/instance/experimental";
235+
236+
/**
237+
* @import { ErrorHandler, ErrorObject } from "@hyperjump/better-json-schema-errors"
238+
*/
239+
240+
/** @type ErrorHandler */
241+
const ErrorHandler = async (normalizedErrors, instance, localization) => {
242+
/** @type ErrorObject[] */
243+
const errors = [];
244+
245+
if (normalizedErrors["https://json-schema.org/keyword/multipleOfTen"]) {
246+
for (const schemaLocation in normalizedErrors["https://json-schema.org/keyword/multipleOfTen"]) {
247+
if (!normalizedErrors["https://json-schema.org/keyword/multipleOfTen"][schemaLocation]) {
248+
errors.push({
249+
message: "Instance must be multiple of 10",
250+
instanceLocation: Instance.uri(instance),
251+
schemaLocation: schemaLocation
252+
});
253+
}
254+
}
255+
}
256+
257+
return errors;
258+
};
259+
260+
261+
```
262+
263+
Step 3:- Register the handlers:
264+
265+
```js
266+
import { setNormalizationHandler, addErrorHandler } from "@hyperjump/better-json-schema-errors";
267+
const KEYWORD_URI = "https://json-schema.org/keyword/multipleOfTen";
268+
269+
setNormalizationHandler(KEYWORD_URI, multipleOften);
270+
271+
addErrorHandler(errorHandler);
272+
```
21273
## API
22274

23275
<https://better-json-schema-errors.hyperjump.io/modules.html>
@@ -29,7 +281,6 @@ changes you'd like to make before implementing it. If it's an obvious bug with
29281
an obvious solution or something simple like a fixing a typo, creating an issue
30282
isn't required. You can just send a PR without creating an issue. Before
31283
submitting any code, please remember to first run the following tests.
32-
33284
- `npm test` (Tests can also be run continuously using `npm test -- --watch`)
34285
- `npm run lint`
35286
- `npm run type-check`

0 commit comments

Comments
 (0)