Skip to content

Commit f0154de

Browse files
committed
update the readme file and added docs folder
1 parent 2792ad9 commit f0154de

File tree

3 files changed

+147
-150
lines changed

3 files changed

+147
-150
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+
44

55
scratch/
66
TODO*

README.md

Lines changed: 27 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ npm install @hyperjump/better-json-schema-errors
1010
## API Error Message Format
1111

1212
Our API Error Format includes :-
13-
- **`schemaLocation`** - A JSON Pointer or 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.
13+
- **`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.
1414

1515
- **`instanceLocation`** - JSON Pointer to the invalid piece of input data.
1616

@@ -38,37 +38,34 @@ environments, so this module may be less stable in those environments.
3838

3939

4040
## Examples and Basic Usage
41-
Better JSON Schema Errors works with **any JSON Schema validator** that follows the official [JSON Schema Output Format](https://json-schema.org/draft/2019-09).
41+
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).
4242
In this example, we’ll showcase it with the [Hyperjump JSON Schema Validator](https://github.com/hyperjump-io/json-schema).
4343

4444
Now let's define a schema and some invalid data, then run the validation and process the output with `better-json-schema-errors`. :-
4545
```js
4646
import { registerSchema, validate, unregisterSchema } from "@hyperjump/json-schema/draft-2020-12";
4747
import { betterJsonSchemaErrors } from "@hyperjump/better-json-schema-errors";
4848

49-
async function runExample() {
50-
const schemaUri = "https://example.com/main";
51-
registerSchema({
52-
$schema: "https://json-schema.org/draft/2020-12/schema",
53-
anyOf: [
54-
{ enum: ["a", "b", "c"] }
55-
]
56-
}, schemaUri);
57-
58-
const instance = 4;
59-
const result = await validate(schemaUri, instance, "BASIC");
60-
61-
if (result.valid) {
62-
console.log("Valid instance!");
63-
} else {
64-
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance);
65-
console.log(JSON.stringify(friendlyErrors, null, 2));
66-
}
67-
68-
unregisterSchema(schemaUri);
49+
const schemaUri = "https://example.com/main";
50+
registerSchema({
51+
$schema: "https://json-schema.org/draft/2020-12/schema",
52+
anyOf: [
53+
{ enum: ["a", "b", "c"] }
54+
]
55+
}, schemaUri);
56+
57+
const instance = 4;
58+
const result = await validate(schemaUri, instance, "BASIC");
59+
60+
if (result.valid) {
61+
console.log("Valid instance!");
62+
} else {
63+
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance);
64+
console.log(JSON.stringify(friendlyErrors, null, 2));
6965
}
7066

71-
await runExample();
67+
unregisterSchema(schemaUri);
68+
7269
```
7370
Output:-
7471
```json
@@ -84,7 +81,7 @@ Output:-
8481
```
8582

8683
## Features and Advanced Usage
87-
Better JSON Schema Errors goes beyond simply rephrasing validation messages. It provides a **robust error normalization layer** on top of the official [JSON Schema Output Format](https://json-schema.org/draft/2019-09), ensuring consistent, human-friendly results across different validators and error formats.
84+
8885
### 1. Works with All Output Formats
8986
Supports all three standardized output formats:
9087
- **BASIC** — The "Basic" structure is a flat list of output units
@@ -95,10 +92,7 @@ schema.
9592

9693
No matter which output format your validator produces, Better JSON Schema Errors can process it.
9794

98-
### 2. Resolves Output Ambiguities
99-
Some validators may provide inconsistent or ambiguous data, such as using `keywordLocation` instead of the required `absoluteKeywordLocation`. Our library resolves these issues by normalizing both the `keywordLocation` and `instanceLocation`. It adds the leading `#` to `instanceLocation` and standardizes the path, so everything is a valid JSON Pointer and can be used predictably. This helps resolve ambiguities and provides a unified, reliable format for all error messages.
100-
101-
### 3. Multiple Schema Locations
95+
### 2. Multiple Schema Locations
10296
Sometimes a single validation issue is tied to **more than one schema keyword**.
10397
For example, when both `minimum` and `exclusiveMinimum` apply, or when `minLength` and `maxLength` constraints overlap or when when both `minimum` and `maximum` apply.
10498

@@ -114,138 +108,22 @@ Instead of generating duplicate error messages, It groups these into an **array
114108
"message": "Expected a number greater than 5 and less than 10."
115109
}
116110
```
117-
### 4. Localization
111+
### 3. Localization
118112

119-
The library uses a [fluent/bundle](https://github.com/projectfluent/fluent.js/tree/main/fluent-bundle) to provide localized error messages. By default, only English is supported.
113+
The library uses [fluent](https://projectfluent.org) `.ftl` files provide localized error messages. By default, only English is supported.
120114

121115
We need contributions from different countries to add more languages.
122116

123117
To change the language, pass a language option to the betterJsonSchemaErrors function, like this:
124118

125119
```
126-
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance, "en-US");
127-
```
128-
### 5. Handling `anyOf` with Clarity
129-
130-
The `anyOf` keyword is a powerful but complex JSON Schema feature. When an instance fails to validate against all subschemas within an `anyOf`, standard validator output can be verbose and confusing, often returning an error for each failed subschema.
131-
132-
**Better JSON Schema Errors** intelligently simplifies this output, providing clear, consolidated error messages that are easier to debug.
133-
134-
---
135-
136-
#### 1. Mismatched Types
137-
138-
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.
139-
140-
**Schema:**
141-
```json
142-
{
143-
"anyOf": [
144-
{ "type": "string" },
145-
{ "type": "number" }
146-
]
147-
}
148-
```
149-
150-
Invalid Instance:-
151-
``` Json
152-
false
153-
```
154-
BetterJSONSchemaErrors Output:-
155-
``` Json
156-
{
157-
"errors": [
158-
{
159-
"schemaLocation": "https://example.com/main#/anyOf",
160-
"instanceLocation": "#",
161-
"message": "The instance should be of type 'string' or 'number' but found 'boolean'."
162-
}
163-
]
164-
}
165-
120+
const friendlyErrors = await betterJsonSchemaErrors(result, schemaUri, instance, { language: "en-US" });
166121
```
167-
#### 2. Partial Match with a Failed Constraint
168122

169-
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.
123+
### 4. Handling `anyOf` with Clarity
170124

171-
**Schema:**
172-
```json
173-
{
174-
"anyOf": [
175-
{ "type": "string", "minLength": 5 },
176-
{ "type": "number" }
177-
]
178-
}
179-
```
125+
The `anyOf` 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. For detailed examples, see the dedicated [**anyOf** documentation](./docs/anyOf.md).
180126

181-
Invalid Instance:-
182-
``` Json
183-
"abc"
184-
```
185-
BetterJSONSchemaErrors Output:-
186-
``` Json
187-
{
188-
"errors": [
189-
{
190-
"schemaLocation": "https://example.com/main#/anyOf/0/minLength",
191-
"instanceLocation": "#",
192-
"message": "Expected a string at least 5 characters long."
193-
}
194-
]
195-
}
196-
197-
```
198-
199-
#### 3. Multiple types match, pick based on field overlap
200-
201-
When an instance matches multiple `anyOf` alternatives type, the library prioritizes the one with the most relevant error based on the instance's fields.
202-
203-
**Schema:**
204-
```json
205-
{
206-
"anyOf": [
207-
{
208-
"type": "object",
209-
"properties": {
210-
"name": { "type": "string" },
211-
"age": { "type": "number" }
212-
},
213-
"required": ["name", "age"]
214-
},
215-
{
216-
"type": "object",
217-
"properties": {
218-
"title": { "type": "string" },
219-
"author": { "type": "string" },
220-
"ID": { "type": "string", "pattern": "^[0-9\\-]+$" }
221-
},
222-
"required": ["title", "author", "ID"]
223-
}
224-
]
225-
}
226-
```
227-
228-
Invalid Instance:-
229-
``` Json
230-
{
231-
"title": "Clean Code",
232-
"author": "Robert Martin",
233-
"ID": "NotValidId"
234-
}
235-
```
236-
BetterJSONSchemaErrors Output:-
237-
``` Json
238-
{
239-
"errors": [
240-
{
241-
"schemaLocation": "https://example.com/main#/anyOf/1/properties/ID/pattern",
242-
"instanceLocation": "#/ID",
243-
"message": "The instance should match the format: \"^[0-9\\-]+$\". "
244-
}
245-
]
246-
}
247-
248-
```
249127
## API
250128

251129
<https://better-json-schema-errors.hyperjump.io/modules.html>

docs/anyOf.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
## Handling `anyOf` with Clarity
2+
3+
**Better JSON Schema Errors** intelligently simplifies error output, providing clear, consolidated error messages that are easier to debug.
4+
Here are the differnt cases and how better-json-schema-errors handles them to produces better errors.
5+
6+
---
7+
8+
#### 1. Mismatched Types
9+
10+
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.
11+
12+
**Schema:**
13+
```json
14+
{
15+
"anyOf": [
16+
{ "type": "string" },
17+
{ "type": "number" }
18+
]
19+
}
20+
```
21+
22+
Invalid Instance:-
23+
``` Json
24+
false
25+
```
26+
BetterJSONSchemaErrors Output:-
27+
``` Json
28+
{
29+
"errors": [
30+
{
31+
"schemaLocation": "https://example.com/main#/anyOf",
32+
"instanceLocation": "#",
33+
"message": "The instance should be of type 'string' or 'number' but found 'boolean'."
34+
}
35+
]
36+
}
37+
38+
```
39+
#### 2. Partial Match with a Failed Constraint
40+
41+
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.
42+
43+
**Schema:**
44+
```json
45+
{
46+
"anyOf": [
47+
{ "type": "string", "minLength": 5 },
48+
{ "type": "number" }
49+
]
50+
}
51+
```
52+
53+
Invalid Instance:-
54+
``` Json
55+
"abc"
56+
```
57+
BetterJSONSchemaErrors Output:-
58+
``` Json
59+
{
60+
"errors": [
61+
{
62+
"schemaLocation": "https://example.com/main#/anyOf/0/minLength",
63+
"instanceLocation": "#",
64+
"message": "Expected a string at least 5 characters long."
65+
}
66+
]
67+
}
68+
69+
```
70+
71+
#### 3. Multiple types match, pick based on field overlap
72+
73+
When an instance matches multiple `anyOf` alternatives type, the library prioritizes the one with the most relevant error based on the instance's fields.
74+
75+
**Schema:**
76+
```json
77+
{
78+
"anyOf": [
79+
{
80+
"type": "object",
81+
"properties": {
82+
"name": { "type": "string" },
83+
"age": { "type": "number" }
84+
},
85+
"required": ["name", "age"]
86+
},
87+
{
88+
"type": "object",
89+
"properties": {
90+
"title": { "type": "string" },
91+
"author": { "type": "string" },
92+
"ID": { "type": "string", "pattern": "^[0-9\\-]+$" }
93+
},
94+
"required": ["title", "author", "ID"]
95+
}
96+
]
97+
}
98+
```
99+
100+
Invalid Instance:-
101+
``` Json
102+
{
103+
"title": "Clean Code",
104+
"author": "Robert Martin",
105+
"ID": "NotValidId"
106+
}
107+
```
108+
BetterJSONSchemaErrors Output:-
109+
``` Json
110+
{
111+
"errors": [
112+
{
113+
"schemaLocation": "https://example.com/main#/anyOf/1/properties/ID/pattern",
114+
"instanceLocation": "#/ID",
115+
"message": "The instance should match the format: \"^[0-9\\-]+$\". "
116+
}
117+
]
118+
}
119+
```

0 commit comments

Comments
 (0)