schema-shield 1.0.0 → 1.0.1
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 +38 -12
- package/dist/formats.d.ts.map +1 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1445 -447
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +1445 -447
- package/dist/keywords/array-keywords.d.ts.map +1 -1
- package/dist/keywords/object-keywords.d.ts.map +1 -1
- package/dist/keywords/other-keywords.d.ts.map +1 -1
- package/dist/keywords/string-keywords.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/deep-freeze.d.ts +5 -0
- package/dist/utils/deep-freeze.d.ts.map +1 -0
- package/dist/utils/has-changed.d.ts +2 -0
- package/dist/utils/has-changed.d.ts.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/{utils.d.ts → utils/main-utils.d.ts} +3 -6
- package/dist/utils/main-utils.d.ts.map +1 -0
- package/dist/utils/pattern-matcher.d.ts +3 -0
- package/dist/utils/pattern-matcher.d.ts.map +1 -0
- package/lib/formats.ts +402 -84
- package/lib/index.ts +494 -46
- package/lib/keywords/array-keywords.ts +215 -21
- package/lib/keywords/number-keywords.ts +1 -1
- package/lib/keywords/object-keywords.ts +218 -113
- package/lib/keywords/other-keywords.ts +229 -76
- package/lib/keywords/string-keywords.ts +97 -7
- package/lib/types.ts +4 -5
- package/lib/utils/deep-freeze.ts +208 -0
- package/lib/utils/has-changed.ts +51 -0
- package/lib/utils/index.ts +4 -0
- package/lib/utils/main-utils.ts +190 -0
- package/lib/utils/pattern-matcher.ts +66 -0
- package/package.json +1 -1
- package/dist/utils.d.ts.map +0 -1
- package/lib/utils.ts +0 -362
package/README.md
CHANGED
|
@@ -4,14 +4,33 @@
|
|
|
4
4
|
|
|
5
5
|
SchemaShield is a secure interpreter for JSON Schema engineered for strict environments and complex domain logic. It prioritizes **architectural stability** and **developer experience** over raw synthetic throughput.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
> 🏆 **Fastest JSON Schema Validator on Bun** — 2.5x faster than ajv, 4x faster than schemasafe
|
|
8
|
+
>
|
|
9
|
+
> 📊 **#3 fastest on Node.js** — 70% ajv speed, 50x faster than jsonschema
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import { SchemaShield } from "schema-shield";
|
|
15
|
+
|
|
16
|
+
const validator = new SchemaShield().compile({
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
name: { type: "string" },
|
|
20
|
+
age: { type: "number" }
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
validator({ name: "John", age: 30 });
|
|
25
|
+
// { valid: true, data: { name: "John", age: 30 } }
|
|
26
|
+
|
|
27
|
+
validator({ name: "John", age: "30" });
|
|
28
|
+
// { valid: false, error: ValidationError }
|
|
29
|
+
```
|
|
11
30
|
|
|
12
31
|
## Table of Contents
|
|
13
32
|
|
|
14
|
-
- [
|
|
33
|
+
- [Quick Start](#quick-start)
|
|
15
34
|
- [Why SchemaShield?](#why-schemashield)
|
|
16
35
|
- [Comparison with Other Approaches](#comparison-with-other-approaches)
|
|
17
36
|
- [Usage](#usage)
|
|
@@ -47,6 +66,7 @@ SchemaShield is a secure interpreter for JSON Schema engineered for strict envir
|
|
|
47
66
|
- [Known Limitations](#known-limitations)
|
|
48
67
|
- [1. Dynamic ID Scope Resolution (Scope Alteration)](#1-dynamic-id-scope-resolution-scope-alteration)
|
|
49
68
|
- [2. Unicode Length Validation](#2-unicode-length-validation)
|
|
69
|
+
- [3. Conservative Equality Path (Performance Trade-off)](#3-conservative-equality-path-performance-trade-off)
|
|
50
70
|
- [Testing](#testing)
|
|
51
71
|
- [Contribute](#contribute)
|
|
52
72
|
- [Legal](#legal)
|
|
@@ -70,7 +90,7 @@ Most validators optimize for "operations per second" in synthetic benchmarks, of
|
|
|
70
90
|
| Feature | SchemaShield | JIT Compilers | Classic Interpreters |
|
|
71
91
|
| :---------------------------- | :-------------------------------------------------- | :------------------------------- | :-------------------- |
|
|
72
92
|
| **Architecture** | **Secure Flat Interpreter** | JIT Compiler (eval/new Function) | Recursive Interpreter |
|
|
73
|
-
| **Relative Speed** | **High (~
|
|
93
|
+
| **Relative Speed** | **High (~70%)** | Reference (100%) | Low (1% - 20%) |
|
|
74
94
|
| **CSP Compliance** | **Native (100% Safe)** | Requires Build Config | Variable |
|
|
75
95
|
| **Edge Ready** | **Native** | Complex Setup | Variable |
|
|
76
96
|
| **Stack Safety** | **Minimized stack usage (non-recursive core loop)** | Risk of Overflow | Risk of Overflow |
|
|
@@ -193,19 +213,19 @@ In runtimes using JavaScriptCore (like Bun), SchemaShield outperforms JIT compil
|
|
|
193
213
|
| Validator | Relative Speed | Context |
|
|
194
214
|
| :----------------- | :------------- | :----------- |
|
|
195
215
|
| **SchemaShield** | **100%** | **Fastest** |
|
|
196
|
-
| ajv | ~
|
|
197
|
-
| @exodus/schemasafe | ~
|
|
216
|
+
| ajv | ~40% | JIT Compiler |
|
|
217
|
+
| @exodus/schemasafe | ~24% | Interpreter |
|
|
198
218
|
| jsonschema | ~2% | Legacy |
|
|
199
219
|
|
|
200
220
|
### 2. Standard Runtimes (Node.js)
|
|
201
221
|
|
|
202
|
-
In V8-based environments (Node.js), SchemaShield maintains elite performance for a secure interpreter, being roughly **
|
|
222
|
+
In V8-based environments (Node.js), SchemaShield maintains elite performance for a secure interpreter, being roughly **70x faster** than legacy libraries.
|
|
203
223
|
|
|
204
224
|
| Validator | Relative Speed | Context |
|
|
205
225
|
| :----------------- | :------------- | :------------------ |
|
|
206
226
|
| ajv | 100% | Reference (JIT) |
|
|
207
|
-
| @exodus/schemasafe | ~
|
|
208
|
-
| **SchemaShield** | **~
|
|
227
|
+
| @exodus/schemasafe | ~74% | Interpreter |
|
|
228
|
+
| **SchemaShield** | **~70%** | **Secure Standard** |
|
|
209
229
|
| jsonschema | ~1% | Legacy |
|
|
210
230
|
|
|
211
231
|
**Key Takeaway:** SchemaShield delivers consistent high performance in Node.js without the security risks, memory leaks, or "cold start" latency associated with code generation.
|
|
@@ -504,7 +524,6 @@ Take into account that the error must be generated using the `defineError` funct
|
|
|
504
524
|
|
|
505
525
|
- `message`: A string that describes the validation error.
|
|
506
526
|
- `options`: An optional object with properties that provide more context for the error:
|
|
507
|
-
|
|
508
527
|
- `item`?: An optional value representing the final item in the path where the validation error occurred. (e.g. index of an array item)
|
|
509
528
|
- `cause`?: An optional `ValidationError` (or `true` in fail-fast mode) that represents the cause of the current error.
|
|
510
529
|
- `data`?: An optional value representing the data that caused the validation error.
|
|
@@ -1086,6 +1105,13 @@ SchemaShield validates `minLength` and `maxLength` based on JavaScript's `length
|
|
|
1086
1105
|
|
|
1087
1106
|
- **Impact:** Emoji or surrogate pairs may be counted as length 2.
|
|
1088
1107
|
|
|
1108
|
+
### 3. Conservative Equality Path (Performance Trade-off)
|
|
1109
|
+
|
|
1110
|
+
For keywords like `enum`, `const`, and `uniqueItems`, SchemaShield prioritizes exact structural comparisons to preserve predictable behavior.
|
|
1111
|
+
|
|
1112
|
+
- **Impact:** For very large arrays or enums with many complex objects, this conservative path can be slower than aggressive hashing strategies.
|
|
1113
|
+
- **Future Option:** An opt-in aggressive mode based on structural hashing/bucketing could improve throughput in those extreme cases, but it is intentionally not enabled by default to avoid edge-case semantic divergence.
|
|
1114
|
+
|
|
1089
1115
|
## Testing
|
|
1090
1116
|
|
|
1091
1117
|
SchemaShield prioritizes reliability and accuracy in JSON Schema validation by using the [JSON Schema Test Suite](https://github.com/json-schema-org/JSON-Schema-Test-Suite).
|
package/dist/formats.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../lib/formats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../lib/formats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA8TzC,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,KAAK,CA4O1D,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/****************** Path: lib/index.ts ******************/
|
|
2
|
-
import { DefineErrorFunction, ValidationError } from "./utils";
|
|
3
|
-
export { ValidationError } from "./utils";
|
|
4
|
-
export { deepClone } from "./utils";
|
|
2
|
+
import { DefineErrorFunction, ValidationError } from "./utils/main-utils";
|
|
3
|
+
export { ValidationError } from "./utils/main-utils";
|
|
4
|
+
export { deepCloneUnfreeze as deepClone } from "./utils/deep-freeze";
|
|
5
5
|
export type Result = void | ValidationError | true;
|
|
6
6
|
export interface KeywordFunction {
|
|
7
7
|
(schema: CompiledSchema, data: any, defineError: DefineErrorFunction, instance: SchemaShield): Result;
|
|
@@ -43,11 +43,22 @@ export declare class SchemaShield {
|
|
|
43
43
|
getType(type: string): TypeFunction | false;
|
|
44
44
|
addFormat(name: string, validator: FormatFunction, overwrite?: boolean): void;
|
|
45
45
|
getFormat(format: string): FormatFunction | false;
|
|
46
|
+
isDefaultFormatValidator(format: string, validator: FormatFunction): boolean;
|
|
46
47
|
addKeyword(name: string, validator: KeywordFunction, overwrite?: boolean): void;
|
|
47
48
|
getKeyword(keyword: string): KeywordFunction | false;
|
|
48
49
|
getSchemaRef(path: string): CompiledSchema | undefined;
|
|
49
50
|
getSchemaById(id: string): CompiledSchema | undefined;
|
|
50
51
|
compile(schema: any): Validator;
|
|
52
|
+
private isPlainObject;
|
|
53
|
+
private isTrivialAlwaysValidSubschema;
|
|
54
|
+
private shallowArrayEquals;
|
|
55
|
+
private flattenAssociativeBranches;
|
|
56
|
+
private flattenSingleWrapperOneOf;
|
|
57
|
+
private normalizeSchemaForCompile;
|
|
58
|
+
private markSchemaHasRef;
|
|
59
|
+
private shouldSkipKeyword;
|
|
60
|
+
private hasRequiredDefaults;
|
|
61
|
+
private isDefaultTypeValidator;
|
|
51
62
|
private compileSchema;
|
|
52
63
|
isSchemaLike(subSchema: any): boolean;
|
|
53
64
|
private linkReferences;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,OAAO,EACL,mBAAmB,EACnB,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"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"}
|