schema-shield 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +305 -50
- package/dist/formats.d.ts +1 -1
- package/dist/formats.d.ts.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +246 -183
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +246 -196
- package/dist/keywords/string-keywords.d.ts.map +1 -1
- package/dist/utils.d.ts +21 -4
- package/dist/utils.d.ts.map +1 -1
- package/lib/formats.ts +191 -49
- package/lib/index.ts +59 -30
- package/lib/keywords/array-keywords.ts +1 -1
- package/lib/keywords/string-keywords.ts +6 -12
- package/lib/utils.ts +61 -14
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -13,8 +13,6 @@ Despite its feature-rich and easy extendable nature, SchemaShield is designed to
|
|
|
13
13
|
- [Usage](#usage)
|
|
14
14
|
- [No Code Generation](#no-code-generation)
|
|
15
15
|
- [Error Handling](#error-handling)
|
|
16
|
-
- [ValidationError Properties](#validationerror-properties)
|
|
17
|
-
- [Get the cause of the error](#get-the-cause-of-the-error)
|
|
18
16
|
- [Adding Custom Types](#adding-custom-types)
|
|
19
17
|
- [Method Signature](#method-signature)
|
|
20
18
|
- [Example: Adding a Custom Type](#example-adding-a-custom-type)
|
|
@@ -26,12 +24,16 @@ Despite its feature-rich and easy extendable nature, SchemaShield is designed to
|
|
|
26
24
|
- [Example: Adding a Custom Keyword](#example-adding-a-custom-keyword)
|
|
27
25
|
- [Complex example: Adding a Custom Keyword that uses the instance](#complex-example-adding-a-custom-keyword-that-uses-the-instance)
|
|
28
26
|
- [No Code Generation Opened Possibilities](#no-code-generation-opened-possibilities)
|
|
27
|
+
- [More on Error Handling](#more-on-error-handling)
|
|
28
|
+
- [ValidationError Properties](#validationerror-properties)
|
|
29
|
+
- [Get the path to the error location](#get-the-path-to-the-error-location)
|
|
30
|
+
- [Get the full error chain as a tree](#get-the-full-error-chain-as-a-tree)
|
|
31
|
+
- [Get the cause of the error](#get-the-cause-of-the-error)
|
|
29
32
|
- [Immutable Mode](#immutable-mode)
|
|
30
33
|
- [TypeScript Support](#typescript-support)
|
|
31
34
|
- [Known Limitations](#known-limitations)
|
|
32
35
|
- [Schema References and Schema Definitions](#schema-references-and-schema-definitions)
|
|
33
36
|
- [Unsupported Formats](#unsupported-formats)
|
|
34
|
-
- [Internationalized Formats](#internationalized-formats)
|
|
35
37
|
- [Testing](#testing)
|
|
36
38
|
- [Contribute](#contribute)
|
|
37
39
|
- [Legal](#legal)
|
|
@@ -44,6 +46,7 @@ Despite its feature-rich and easy extendable nature, SchemaShield is designed to
|
|
|
44
46
|
- Immutable mode for data protection.
|
|
45
47
|
- Lightweight and fast.
|
|
46
48
|
- Easy to use and extend.
|
|
49
|
+
- No dependencies.
|
|
47
50
|
- Typescript support.
|
|
48
51
|
|
|
49
52
|
## Usage
|
|
@@ -124,9 +127,9 @@ if (validationResult.valid) {
|
|
|
124
127
|
|
|
125
128
|
**`validationResult`**: Contains the following properties:
|
|
126
129
|
|
|
127
|
-
- `data`: The validated (and potentially modified) data
|
|
128
|
-
- `error`: A `ValidationError` instance if validation failed, otherwise null
|
|
129
|
-
- `valid`: true if validation was successful, otherwise false
|
|
130
|
+
- `data`: The validated (and potentially modified) data.
|
|
131
|
+
- `error`: A `ValidationError` instance if validation failed, otherwise null.
|
|
132
|
+
- `valid`: true if validation was successful, otherwise false.
|
|
130
133
|
|
|
131
134
|
## No Code Generation
|
|
132
135
|
|
|
@@ -147,30 +150,14 @@ You can see a full example of this in the [No Code Generation opened possibiliti
|
|
|
147
150
|
|
|
148
151
|
## Error Handling
|
|
149
152
|
|
|
150
|
-
SchemaShield provides
|
|
151
|
-
|
|
152
|
-
This returned error instance uses the new [Error: cause](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) property introduced in ES6. This allows you to analyze the whole error chain or to retrieve the root cause of the error using the `getCause()` method.
|
|
153
|
-
|
|
154
|
-
### ValidationError Properties
|
|
155
|
-
|
|
156
|
-
- `message`: A string containing a description of the error
|
|
157
|
-
- `item`: The final item in the path that caused the error
|
|
158
|
-
- `keyword`: The keyword that triggered the error
|
|
159
|
-
- `cause`: A nested ValidationError that caused the current error
|
|
160
|
-
- `path`: The JSON Pointer path to the error location in the schema (Only available using the `getCause()` method)
|
|
161
|
-
- `data`: The data that caused the error (optional)
|
|
162
|
-
- `schema`: The compiled schema that caused the error (optional)
|
|
163
|
-
|
|
164
|
-
### Get the cause of the error
|
|
165
|
-
|
|
166
|
-
You can use the `getCause()` method to retrieve the root cause of a validation error. This method returns the nested ValidationError instance that triggered the current error and contains the `path` property.
|
|
153
|
+
SchemaShield provides comprehensive error handling for schema validation. When a validation error occurs, a `ValidationError` instance is returned in the error property of the validation result. This error has the `getPath()` method, which is particularly useful for quickly identifying the location of an error in both the schema and the data.
|
|
167
154
|
|
|
168
155
|
**Example:**
|
|
169
156
|
|
|
170
157
|
```javascript
|
|
171
158
|
import { SchemaShield } from "schema-shield";
|
|
172
159
|
|
|
173
|
-
const schemaShield = new SchemaShield(
|
|
160
|
+
const schemaShield = new SchemaShield();
|
|
174
161
|
|
|
175
162
|
const schema = {
|
|
176
163
|
type: "object",
|
|
@@ -197,16 +184,15 @@ if (validationResult.valid) {
|
|
|
197
184
|
} else {
|
|
198
185
|
console.error("Validation error:", validationResult.error.message); // "Property is invalid"
|
|
199
186
|
|
|
200
|
-
// Get the
|
|
201
|
-
const
|
|
202
|
-
console.error("
|
|
203
|
-
console.error("
|
|
204
|
-
console.error("Error data:", errorCause.data); // 15
|
|
205
|
-
console.error("Error schema:", errorCause.schema); // 18
|
|
206
|
-
console.error("Error keyword:", errorCause.keyword); // "minimum"
|
|
187
|
+
// Get the paths to the error location in the schema and in the data
|
|
188
|
+
const errorPaths = validationResult.error.getPath();
|
|
189
|
+
console.error("Schema path:", errorPaths.schemaPath); // "#/properties/age/minimum"
|
|
190
|
+
console.error("Instance path:", errorPaths.instancePath); // "#/age"
|
|
207
191
|
}
|
|
208
192
|
```
|
|
209
193
|
|
|
194
|
+
For more advanced error handling and a detailed explanation of the ValidationError properties and methods, refer to the [More on Error Handling](#more-on-error-handling) section.
|
|
195
|
+
|
|
210
196
|
## Adding Custom Types
|
|
211
197
|
|
|
212
198
|
SchemaShield allows you to add custom types for validation using the `addType` method.
|
|
@@ -218,11 +204,12 @@ interface TypeFunction {
|
|
|
218
204
|
(data: any): boolean;
|
|
219
205
|
}
|
|
220
206
|
|
|
221
|
-
addType(name: string, validator: TypeFunction): void;
|
|
207
|
+
addType(name: string, validator: TypeFunction, overwrite?: boolean): void;
|
|
222
208
|
```
|
|
223
209
|
|
|
224
210
|
- `name`: The name of the custom type. This should be a unique string that does not conflict with existing types.
|
|
225
211
|
- `validator`: A `TypeFunction` that takes a single argument `data` and returns a boolean value. The function should return `true` if the provided data is valid for the custom type, and `false` otherwise.
|
|
212
|
+
- `overwrite` (optional): Set to `true` to overwrite an existing type with the same name. Default is `false`. If set to `false` and a type with the same name already exists, an error will be thrown.
|
|
226
213
|
|
|
227
214
|
### Example: Adding a Custom Type
|
|
228
215
|
|
|
@@ -276,11 +263,12 @@ interface FormatFunction {
|
|
|
276
263
|
(data: any): boolean;
|
|
277
264
|
}
|
|
278
265
|
|
|
279
|
-
addFormat(name: string, validator: FormatFunction): void;
|
|
266
|
+
addFormat(name: string, validator: FormatFunction, overwrite?: boolean): void;
|
|
280
267
|
```
|
|
281
268
|
|
|
282
269
|
- `name`: The name of the custom format. This should be a unique string that does not conflict with existing formats.
|
|
283
270
|
- `validator`: A FormatFunction that takes a single argument data and returns a boolean value. The function should return true if the provided data is valid for the custom format, and false otherwise.
|
|
271
|
+
- `overwrite` (optional): Set to true to overwrite an existing format with the same name. Default is false. If set to false and a format with the same name already exists, an error will be thrown.
|
|
284
272
|
|
|
285
273
|
### Example: Adding a Custom Format
|
|
286
274
|
|
|
@@ -333,7 +321,7 @@ SchemaShield allows you to add custom keywords for validation using the addKeywo
|
|
|
333
321
|
```javascript
|
|
334
322
|
type Result = void | ValidationError;
|
|
335
323
|
|
|
336
|
-
|
|
324
|
+
interface DefineErrorOptions {
|
|
337
325
|
item?: any; // Final item in the path
|
|
338
326
|
cause?: ValidationError; // Cause of the error
|
|
339
327
|
data?: any; // Data that caused the error
|
|
@@ -352,6 +340,28 @@ interface CompiledSchema {
|
|
|
352
340
|
[key: string]: any;
|
|
353
341
|
}
|
|
354
342
|
|
|
343
|
+
interface FormatFunction {
|
|
344
|
+
(data: any): boolean;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
interface TypeFunction {
|
|
348
|
+
(data: any): boolean;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
declare class SchemaShield {
|
|
352
|
+
constructor({ immutable }?: {
|
|
353
|
+
immutable?: boolean;
|
|
354
|
+
});
|
|
355
|
+
compile(schema: any): Validator;
|
|
356
|
+
addType(name: string, validator: TypeFunction, overwrite?: boolean): void;
|
|
357
|
+
addFormat(name: string, validator: FormatFunction, overwrite?: boolean): void;
|
|
358
|
+
addKeyword(name: string, validator: KeywordFunction, overwrite?: boolean): void;
|
|
359
|
+
getType(type: string): TypeFunction | false;
|
|
360
|
+
getFormat(format: string): FormatFunction | false;
|
|
361
|
+
getKeyword(keyword: string): KeywordFunction | false;
|
|
362
|
+
isSchemaLike(subSchema: any): boolean;
|
|
363
|
+
}
|
|
364
|
+
|
|
355
365
|
interface KeywordFunction {
|
|
356
366
|
(
|
|
357
367
|
schema: CompiledSchema,
|
|
@@ -361,11 +371,14 @@ interface KeywordFunction {
|
|
|
361
371
|
): Result;
|
|
362
372
|
}
|
|
363
373
|
|
|
364
|
-
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
addKeyword(name: string, validator: KeywordFunction, overwrite?: boolean): void;
|
|
365
377
|
```
|
|
366
378
|
|
|
367
379
|
- `name`: The name of the custom keyword. This should be a unique string that does not conflict with existing keywords.
|
|
368
380
|
- `validator`: A `KeywordFunction` that takes four arguments: `schema`, `data`, `defineError`, and `instance` (The SchemaShield instance that is currently running the validation). The function should not return anything if the data is valid for the custom keyword, and should return a `ValidationError` instance if the data is invalid.
|
|
381
|
+
- `overwrite` (optional): Set to true to overwrite an existing keyword with the same name. Default is false. If set to false and a keyword with the same name already exists, an error will be thrown.
|
|
369
382
|
|
|
370
383
|
#### About the `defineError` Function
|
|
371
384
|
|
|
@@ -388,7 +401,7 @@ In this example, we'll add a custom keyword called divisibleBy that validates if
|
|
|
388
401
|
```javascript
|
|
389
402
|
import { SchemaShield, ValidationError } from "./path/to/SchemaShield";
|
|
390
403
|
|
|
391
|
-
const schemaShield = new SchemaShield(
|
|
404
|
+
const schemaShield = new SchemaShield();
|
|
392
405
|
|
|
393
406
|
// Custom keyword 'divisibleBy' validator function
|
|
394
407
|
const divisibleByValidator = (schema, data, defineError, instance) => {
|
|
@@ -465,9 +478,9 @@ const prefixedUsername = (schema, data, defineError, instance) => {
|
|
|
465
478
|
|
|
466
479
|
// Get the validators for the specified types and formats from the instance
|
|
467
480
|
// (if they exist)
|
|
468
|
-
const typeValidator = instance.
|
|
469
|
-
const prefixValidator = instance.
|
|
470
|
-
const formatValidator = instance.
|
|
481
|
+
const typeValidator = instance.getType(validType);
|
|
482
|
+
const prefixValidator = instance.getKeyword(prefixValidator);
|
|
483
|
+
const formatValidator = instance.getFormat(validFormat);
|
|
471
484
|
|
|
472
485
|
for (let i = 0; i < data.length; i++) {
|
|
473
486
|
const item = data[i];
|
|
@@ -572,9 +585,9 @@ schemaShield.addKeyword(
|
|
|
572
585
|
(schema, data, defineError, instance) => {
|
|
573
586
|
const { assignment, project, employee } = data;
|
|
574
587
|
|
|
575
|
-
const stringTypeValidator = instance.
|
|
576
|
-
const projectTypeValidator = instance.
|
|
577
|
-
const employeeTypeValidator = instance.
|
|
588
|
+
const stringTypeValidator = instance.getType("string");
|
|
589
|
+
const projectTypeValidator = instance.getType("project");
|
|
590
|
+
const employeeTypeValidator = instance.getType("employee");
|
|
578
591
|
|
|
579
592
|
if (!stringTypeValidator(assignment)) {
|
|
580
593
|
return defineError("Assignment must be a string", {
|
|
@@ -651,6 +664,255 @@ if (validationResult.valid) {
|
|
|
651
664
|
|
|
652
665
|
In this example, SchemaShield safely accesses instances of custom classes and utilizes them in the validation process. This level of complexity and flexibility would not be possible or would require a lot of boilerplate code with other libraries that rely on code generation.
|
|
653
666
|
|
|
667
|
+
## More on Error Handling
|
|
668
|
+
|
|
669
|
+
SchemaShield provides a `ValidationError` class to handle errors that occur during schema validation. When a validation error is encountered, a `ValidationError` instance is returned in the error property of the validation result.
|
|
670
|
+
|
|
671
|
+
This error instance uses the new [Error: cause](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) property introduced in ES6. This allows you to analyze the whole error chain or to retrieve the root cause of the error using the `getCause()` `getTree()` and `getPath()` methods.
|
|
672
|
+
|
|
673
|
+
### ValidationError Properties
|
|
674
|
+
|
|
675
|
+
- `message`: A string containing a description of the error.
|
|
676
|
+
- `item`: The final item in the path that caused the error (either a string or a number) (optional).
|
|
677
|
+
- `keyword`: The keyword that triggered the error.
|
|
678
|
+
- `cause`: A nested ValidationError or a normal Error that caused the current error.
|
|
679
|
+
- `schemaPath`: The JSON Pointer path to the error location in the schema.
|
|
680
|
+
- `instancePath`: The JSON Pointer path to the error location in the data.
|
|
681
|
+
- `data`: The data that caused the error (optional).
|
|
682
|
+
- `schema`: The schema that caused the error (optional).
|
|
683
|
+
|
|
684
|
+
_Note:_ The `schemaPath` and `instancePath` will be only available after using the `getCause()` `getTree()` or `getPath()` methods.
|
|
685
|
+
|
|
686
|
+
### Get the path to the error location
|
|
687
|
+
|
|
688
|
+
You can use the `getPath` method to get the JSON Pointer path to the error location in the schema and in the data. This method returns an object containing the `schemaPath` and `instancePath`.
|
|
689
|
+
|
|
690
|
+
**Example:**
|
|
691
|
+
|
|
692
|
+
```javascript
|
|
693
|
+
import { SchemaShield } from "schema-shield";
|
|
694
|
+
|
|
695
|
+
const schemaShield = new SchemaShield();
|
|
696
|
+
|
|
697
|
+
const schema = {
|
|
698
|
+
type: "object",
|
|
699
|
+
properties: {
|
|
700
|
+
description: { type: "string" },
|
|
701
|
+
shouldLoadDb: { type: "boolean" },
|
|
702
|
+
enableNetConnectFor: { type: "array", items: { type: "string" } },
|
|
703
|
+
params: {
|
|
704
|
+
type: "object",
|
|
705
|
+
additionalProperties: {
|
|
706
|
+
type: "object",
|
|
707
|
+
properties: {
|
|
708
|
+
description: { type: "string" },
|
|
709
|
+
default: { type: "string" }
|
|
710
|
+
},
|
|
711
|
+
required: ["description"]
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
run: { type: "string" }
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
const validator = schemaShield.compile(schema);
|
|
719
|
+
|
|
720
|
+
const invalidData = {
|
|
721
|
+
description: "Say hello to the bot.",
|
|
722
|
+
shouldLoadDb: false,
|
|
723
|
+
enableNetConnectFor: [],
|
|
724
|
+
params: {
|
|
725
|
+
color: {
|
|
726
|
+
type: "string",
|
|
727
|
+
// description: "The color of the text", // Missing description on purpose
|
|
728
|
+
default: "red"
|
|
729
|
+
}
|
|
730
|
+
},
|
|
731
|
+
run: "run"
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
const validationResult = validator(invalidData);
|
|
735
|
+
|
|
736
|
+
if (validationResult.valid) {
|
|
737
|
+
console.log("Data is valid:", validationResult.data);
|
|
738
|
+
} else {
|
|
739
|
+
console.error("Validation error:", validationResult.error.message); // "Property is invalid"
|
|
740
|
+
|
|
741
|
+
// Get the paths to the error location in the schema and in the data
|
|
742
|
+
const errorPaths = validationResult.error.getPath();
|
|
743
|
+
console.error("Schema path:", errorPaths.schemaPath); // "#/properties/params/additionalProperties/required"
|
|
744
|
+
console.error("Instance path:", errorPaths.instancePath); // "#/params/color/description"
|
|
745
|
+
}
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Get the full error chain as a tree
|
|
749
|
+
|
|
750
|
+
You can use the `getTree()` method to retrieve the full error chain as a tree. This method returns an ErrorTree object with the complete nested error structure, allowing you to analyze the full chain of errors that occurred during validation.
|
|
751
|
+
|
|
752
|
+
#### ErrorTree Signature
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
interface ErrorTree {
|
|
756
|
+
message: string; // The error message
|
|
757
|
+
keyword: string; // The keyword that triggered the error
|
|
758
|
+
item?: string | number; // The final item in the path that caused the error (either a string or a number) (optional)
|
|
759
|
+
schemaPath: string; // The JSON Pointer path to the error location in the schema
|
|
760
|
+
instancePath: string; // The JSON Pointer path to the error location in the data
|
|
761
|
+
data?: any; // The data that caused the error (optional)
|
|
762
|
+
cause?: ErrorTree; // A nested ErrorTree representation of the nested error that caused the current error
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
**Example:**
|
|
767
|
+
|
|
768
|
+
```javascript
|
|
769
|
+
import { SchemaShield } from "schema-shield";
|
|
770
|
+
|
|
771
|
+
const schemaShield = new SchemaShield();
|
|
772
|
+
|
|
773
|
+
const schema = {
|
|
774
|
+
type: "object",
|
|
775
|
+
properties: {
|
|
776
|
+
description: { type: "string" },
|
|
777
|
+
shouldLoadDb: { type: "boolean" },
|
|
778
|
+
enableNetConnectFor: { type: "array", items: { type: "string" } },
|
|
779
|
+
params: {
|
|
780
|
+
type: "object",
|
|
781
|
+
additionalProperties: {
|
|
782
|
+
type: "object",
|
|
783
|
+
properties: {
|
|
784
|
+
description: { type: "string" },
|
|
785
|
+
default: { type: "string" }
|
|
786
|
+
},
|
|
787
|
+
required: ["description"]
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
run: { type: "string" }
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
const validator = schemaShield.compile(schema);
|
|
795
|
+
|
|
796
|
+
const invalidData = {
|
|
797
|
+
description: "Say hello to the bot.",
|
|
798
|
+
shouldLoadDb: false,
|
|
799
|
+
enableNetConnectFor: [],
|
|
800
|
+
params: {
|
|
801
|
+
color: {
|
|
802
|
+
type: "string",
|
|
803
|
+
// description: "The color of the text", // Missing description on purpose
|
|
804
|
+
default: "red"
|
|
805
|
+
}
|
|
806
|
+
},
|
|
807
|
+
run: "run"
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
const validationResult = validator(invalidData);
|
|
811
|
+
|
|
812
|
+
if (validationResult.valid) {
|
|
813
|
+
console.log("Data is valid:", validationResult.data);
|
|
814
|
+
} else {
|
|
815
|
+
console.error("Validation error:", validationResult.error.message); // "Property is invalid"
|
|
816
|
+
|
|
817
|
+
// Get the full error chain as a tree
|
|
818
|
+
const errorTree = validationResult.error.getTree();
|
|
819
|
+
console.error(errorTree);
|
|
820
|
+
|
|
821
|
+
/*
|
|
822
|
+
{
|
|
823
|
+
message: "Property is invalid",
|
|
824
|
+
keyword: "properties",
|
|
825
|
+
item: "params",
|
|
826
|
+
schemaPath: "#/properties/params",
|
|
827
|
+
instancePath: "#/params",
|
|
828
|
+
data: { color: { type: "string", default: "red" } },
|
|
829
|
+
cause: {
|
|
830
|
+
message: "Additional properties are invalid",
|
|
831
|
+
keyword: "additionalProperties",
|
|
832
|
+
item: "color",
|
|
833
|
+
schemaPath: "#/properties/params/additionalProperties",
|
|
834
|
+
instancePath: "#/params/color",
|
|
835
|
+
data: { type: "string", default: "red" },
|
|
836
|
+
cause: {
|
|
837
|
+
message: "Required property is missing",
|
|
838
|
+
keyword: "required",
|
|
839
|
+
item: "description",
|
|
840
|
+
schemaPath: "#/properties/params/additionalProperties/required",
|
|
841
|
+
instancePath: "#/params/color/description",
|
|
842
|
+
data: undefined
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
*/
|
|
847
|
+
}
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
The `errorTree` object contains the full error chain with nested causes, allowing you to analyze the entire error structure.
|
|
851
|
+
|
|
852
|
+
### Get the cause of the error
|
|
853
|
+
|
|
854
|
+
You can use the `getCause()` method to retrieve the root cause of a validation error. This method returns the nested ValidationError instance that triggered the current error and contains the `schemaPath` and `instancePath` properties.
|
|
855
|
+
|
|
856
|
+
```javascript
|
|
857
|
+
import { SchemaShield } from "schema-shield";
|
|
858
|
+
|
|
859
|
+
const schemaShield = new SchemaShield();
|
|
860
|
+
|
|
861
|
+
const schema = {
|
|
862
|
+
type: "object",
|
|
863
|
+
properties: {
|
|
864
|
+
description: { type: "string" },
|
|
865
|
+
shouldLoadDb: { type: "boolean" },
|
|
866
|
+
enableNetConnectFor: { type: "array", items: { type: "string" } },
|
|
867
|
+
params: {
|
|
868
|
+
type: "object",
|
|
869
|
+
additionalProperties: {
|
|
870
|
+
type: "object",
|
|
871
|
+
properties: {
|
|
872
|
+
description: { type: "string" },
|
|
873
|
+
default: { type: "string" }
|
|
874
|
+
},
|
|
875
|
+
required: ["description"]
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
run: { type: "string" }
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
const validator = schemaShield.compile(schema);
|
|
883
|
+
|
|
884
|
+
const invalidData = {
|
|
885
|
+
description: "Say hello to the bot.",
|
|
886
|
+
shouldLoadDb: false,
|
|
887
|
+
enableNetConnectFor: [],
|
|
888
|
+
params: {
|
|
889
|
+
color: {
|
|
890
|
+
type: "string",
|
|
891
|
+
// description: "The color of the text", // Missing description on purpose
|
|
892
|
+
default: "red"
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
run: "run"
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
const validationResult = validator(invalidData);
|
|
899
|
+
|
|
900
|
+
if (validationResult.valid) {
|
|
901
|
+
console.log("Data is valid:", validationResult.data);
|
|
902
|
+
} else {
|
|
903
|
+
console.error("Validation error:", validationResult.error.message); // "Property is invalid"
|
|
904
|
+
|
|
905
|
+
// Get the root cause of the error
|
|
906
|
+
const errorCause = validationResult.error.getCause();
|
|
907
|
+
console.error("Root cause:", errorCause.message); // "Required property is missing"
|
|
908
|
+
console.error("Schema path:", errorCause.schemaPath); // "#/properties/params/additionalProperties/required"
|
|
909
|
+
console.error("Instance path:", errorCause.instancePath); // "#/params/color/description"
|
|
910
|
+
console.error("Error data:", errorCause.data); // undefined
|
|
911
|
+
console.error("Error schema:", errorCause.schema); // ["description"]
|
|
912
|
+
console.error("Error keyword:", errorCause.keyword); // "required"
|
|
913
|
+
}
|
|
914
|
+
```
|
|
915
|
+
|
|
654
916
|
## Immutable Mode
|
|
655
917
|
|
|
656
918
|
SchemaShield offers an optional immutable mode to prevent modifications to the input data during validation. In some cases, SchemaShield may mutate the data when using the `default` keyword or within custom added keywords.
|
|
@@ -685,14 +947,7 @@ For now, consider using custom implementations using the `addKeyword` method or
|
|
|
685
947
|
|
|
686
948
|
### Unsupported Formats
|
|
687
949
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
- `duration`
|
|
691
|
-
- `uuid`
|
|
692
|
-
- `uri-reference`
|
|
693
|
-
- `uri-template`
|
|
694
|
-
|
|
695
|
-
### Internationalized Formats
|
|
950
|
+
#### Internationalized Formats
|
|
696
951
|
|
|
697
952
|
There is no plan to support the following formats in SchemaShield, as they are not relevant to the majority of use cases. If you need to use these formats, consider using custom implementations using the `addFormat` method to handle them.
|
|
698
953
|
|
package/dist/formats.d.ts
CHANGED
package/dist/formats.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../lib/formats.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../lib/formats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,KAAK,CA+O1D,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,16 +25,19 @@ export interface Validator {
|
|
|
25
25
|
compiledSchema: CompiledSchema;
|
|
26
26
|
}
|
|
27
27
|
export declare class SchemaShield {
|
|
28
|
-
types
|
|
29
|
-
formats
|
|
30
|
-
keywords
|
|
31
|
-
immutable
|
|
28
|
+
private types;
|
|
29
|
+
private formats;
|
|
30
|
+
private keywords;
|
|
31
|
+
private immutable;
|
|
32
32
|
constructor({ immutable }?: {
|
|
33
33
|
immutable?: boolean;
|
|
34
34
|
});
|
|
35
|
-
addType(name: string, validator: TypeFunction): void;
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
addType(name: string, validator: TypeFunction, overwrite?: boolean): void;
|
|
36
|
+
getType(type: string): TypeFunction | false;
|
|
37
|
+
addFormat(name: string, validator: FormatFunction, overwrite?: boolean): void;
|
|
38
|
+
getFormat(format: string): FormatFunction | false;
|
|
39
|
+
addKeyword(name: string, validator: KeywordFunction, overwrite?: boolean): void;
|
|
40
|
+
getKeyword(keyword: string): KeywordFunction | false;
|
|
38
41
|
compile(schema: any): Validator;
|
|
39
42
|
private compileSchema;
|
|
40
43
|
isSchemaLike(subSchema: any): boolean;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,eAAe,EAKhB,MAAM,SAAS,CAAC;AAMjB,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,eAAe,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,CACE,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,mBAAmB,EAChC,QAAQ,EAAE,YAAY,GACrB,MAAM,CAAC;CACX;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,IAAI,EAAE,GAAG,GAAG;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1E,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,qBAAa,YAAY;IACvB,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,eAAe,EAKhB,MAAM,SAAS,CAAC;AAMjB,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,eAAe,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,CACE,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,mBAAmB,EAChC,QAAQ,EAAE,YAAY,GACrB,MAAM,CAAC;CACX;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,IAAI,EAAE,GAAG,GAAG;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1E,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,OAAO,CAA8C;IAC7D,OAAO,CAAC,QAAQ,CAA+C;IAC/D,OAAO,CAAC,SAAS,CAAS;gBAEd,EACV,SAAiB,EAClB,GAAE;QACD,SAAS,CAAC,EAAE,OAAO,CAAC;KAChB;IAoBN,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,UAAQ;IAOhE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,KAAK;IAI3C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,UAAQ;IAOpE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,KAAK;IAIjD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,UAAQ;IAOtE,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,KAAK;IAIpD,OAAO,CAAC,MAAM,EAAE,GAAG,GAAG,SAAS;IA6B/B,OAAO,CAAC,aAAa;IA0IrB,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO;CActC"}
|