z-schema 9.0.1 → 10.0.0

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.
Files changed (59) hide show
  1. package/README.md +123 -191
  2. package/cjs/index.d.ts +33 -9
  3. package/cjs/index.js +4799 -3984
  4. package/dist/errors.js +5 -0
  5. package/dist/format-validators.js +65 -0
  6. package/dist/json-schema-versions.js +5 -0
  7. package/dist/json-schema.js +11 -4
  8. package/dist/json-validation.js +151 -10
  9. package/dist/report.js +2 -3
  10. package/dist/schema-cache.js +23 -2
  11. package/dist/schema-compiler.js +25 -10
  12. package/dist/schema-validator.js +66 -45
  13. package/dist/schemas/draft-06-hyper-schema.json +132 -0
  14. package/dist/schemas/draft-06-links.json +43 -0
  15. package/dist/schemas/draft-06-schema.json +155 -0
  16. package/dist/types/errors.d.ts +4 -0
  17. package/dist/types/index.d.ts +2 -1
  18. package/dist/types/json-schema-versions.d.ts +23 -0
  19. package/dist/types/json-schema.d.ts +5 -9
  20. package/dist/types/json-validation.d.ts +3 -3
  21. package/dist/types/report.d.ts +3 -3
  22. package/dist/types/schema-cache.d.ts +1 -1
  23. package/dist/types/schema-compiler.d.ts +1 -1
  24. package/dist/types/schema-validator.d.ts +1 -1
  25. package/dist/types/utils/what-is.d.ts +1 -0
  26. package/dist/types/z-schema-base.d.ts +1 -1
  27. package/dist/types/z-schema-options.d.ts +1 -1
  28. package/dist/types/z-schema-reader.d.ts +1 -1
  29. package/dist/types/z-schema-versions.d.ts +1 -0
  30. package/dist/types/z-schema.d.ts +10 -1
  31. package/dist/utils/schema-regex.js +4 -3
  32. package/dist/utils/what-is.js +4 -1
  33. package/dist/z-schema-base.js +4 -5
  34. package/dist/z-schema-options.js +3 -1
  35. package/dist/z-schema-versions.js +27 -0
  36. package/dist/z-schema.js +21 -7
  37. package/package.json +2 -2
  38. package/src/errors.ts +6 -0
  39. package/src/format-validators.ts +65 -0
  40. package/src/index.ts +2 -1
  41. package/src/json-schema-versions.ts +34 -0
  42. package/src/json-schema.ts +22 -16
  43. package/src/json-validation.ts +183 -13
  44. package/src/report.ts +5 -6
  45. package/src/schema-cache.ts +25 -3
  46. package/src/schema-compiler.ts +25 -11
  47. package/src/schema-validator.ts +128 -62
  48. package/src/schemas/draft-06-hyper-schema.json +133 -0
  49. package/src/schemas/draft-06-links.json +43 -0
  50. package/src/schemas/draft-06-schema.json +155 -0
  51. package/src/utils/schema-regex.ts +5 -3
  52. package/src/utils/what-is.ts +5 -1
  53. package/src/z-schema-base.ts +5 -6
  54. package/src/z-schema-options.ts +3 -2
  55. package/src/z-schema-reader.ts +1 -1
  56. package/src/z-schema-versions.ts +38 -0
  57. package/src/z-schema.ts +27 -11
  58. package/umd/ZSchema.js +5100 -4285
  59. package/umd/ZSchema.min.js +1 -1
@@ -0,0 +1,155 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-06/schema#",
3
+ "$id": "http://json-schema.org/draft-06/schema#",
4
+ "title": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "nonNegativeInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "nonNegativeIntegerDefault0": {
16
+ "allOf": [
17
+ { "$ref": "#/definitions/nonNegativeInteger" },
18
+ { "default": 0 }
19
+ ]
20
+ },
21
+ "simpleTypes": {
22
+ "enum": [
23
+ "array",
24
+ "boolean",
25
+ "integer",
26
+ "null",
27
+ "number",
28
+ "object",
29
+ "string"
30
+ ]
31
+ },
32
+ "stringArray": {
33
+ "type": "array",
34
+ "items": { "type": "string" },
35
+ "uniqueItems": true,
36
+ "default": []
37
+ }
38
+ },
39
+ "type": ["object", "boolean"],
40
+ "properties": {
41
+ "$id": {
42
+ "type": "string",
43
+ "format": "uri-reference"
44
+ },
45
+ "$schema": {
46
+ "type": "string",
47
+ "format": "uri"
48
+ },
49
+ "$ref": {
50
+ "type": "string",
51
+ "format": "uri-reference"
52
+ },
53
+ "title": {
54
+ "type": "string"
55
+ },
56
+ "description": {
57
+ "type": "string"
58
+ },
59
+ "default": {},
60
+ "examples": {
61
+ "type": "array",
62
+ "items": {}
63
+ },
64
+ "multipleOf": {
65
+ "type": "number",
66
+ "exclusiveMinimum": 0
67
+ },
68
+ "maximum": {
69
+ "type": "number"
70
+ },
71
+ "exclusiveMaximum": {
72
+ "type": "number"
73
+ },
74
+ "minimum": {
75
+ "type": "number"
76
+ },
77
+ "exclusiveMinimum": {
78
+ "type": "number"
79
+ },
80
+ "maxLength": { "$ref": "#/definitions/nonNegativeInteger" },
81
+ "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
82
+ "pattern": {
83
+ "type": "string",
84
+ "format": "regex"
85
+ },
86
+ "additionalItems": { "$ref": "#" },
87
+ "items": {
88
+ "anyOf": [
89
+ { "$ref": "#" },
90
+ { "$ref": "#/definitions/schemaArray" }
91
+ ],
92
+ "default": {}
93
+ },
94
+ "maxItems": { "$ref": "#/definitions/nonNegativeInteger" },
95
+ "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
96
+ "uniqueItems": {
97
+ "type": "boolean",
98
+ "default": false
99
+ },
100
+ "contains": { "$ref": "#" },
101
+ "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" },
102
+ "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" },
103
+ "required": { "$ref": "#/definitions/stringArray" },
104
+ "additionalProperties": { "$ref": "#" },
105
+ "definitions": {
106
+ "type": "object",
107
+ "additionalProperties": { "$ref": "#" },
108
+ "default": {}
109
+ },
110
+ "properties": {
111
+ "type": "object",
112
+ "additionalProperties": { "$ref": "#" },
113
+ "default": {}
114
+ },
115
+ "patternProperties": {
116
+ "type": "object",
117
+ "additionalProperties": { "$ref": "#" },
118
+ "propertyNames": { "format": "regex" },
119
+ "default": {}
120
+ },
121
+ "dependencies": {
122
+ "type": "object",
123
+ "additionalProperties": {
124
+ "anyOf": [
125
+ { "$ref": "#" },
126
+ { "$ref": "#/definitions/stringArray" }
127
+ ]
128
+ }
129
+ },
130
+ "propertyNames": { "$ref": "#" },
131
+ "const": {},
132
+ "enum": {
133
+ "type": "array",
134
+ "minItems": 1,
135
+ "uniqueItems": true
136
+ },
137
+ "type": {
138
+ "anyOf": [
139
+ { "$ref": "#/definitions/simpleTypes" },
140
+ {
141
+ "type": "array",
142
+ "items": { "$ref": "#/definitions/simpleTypes" },
143
+ "minItems": 1,
144
+ "uniqueItems": true
145
+ }
146
+ ]
147
+ },
148
+ "format": { "type": "string" },
149
+ "allOf": { "$ref": "#/definitions/schemaArray" },
150
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
151
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
152
+ "not": { "$ref": "#" }
153
+ },
154
+ "default": {}
155
+ }
@@ -4,9 +4,11 @@
4
4
  export function compileSchemaRegex(
5
5
  pattern: string
6
6
  ): { ok: true; value: RegExp } | { ok: false; error: { pattern: string; message: string } } {
7
- // Detect Unicode property escapes
8
- const unicodeEscape = /\\[pP]{/;
9
- const needsUnicode = unicodeEscape.test(pattern);
7
+ const unicodePropertyEscape = /\\[pP]{/;
8
+ const nonBmpCharacter = /[\u{10000}-\u{10FFFF}]/u;
9
+ const surrogatePairEscape = /\\uD[89AB][0-9A-Fa-f]{2}\\uD[CDEF][0-9A-Fa-f]{2}/;
10
+ const needsUnicode =
11
+ unicodePropertyEscape.test(pattern) || nonBmpCharacter.test(pattern) || surrogatePairEscape.test(pattern);
10
12
  // Try compiling without 'u' flag if not needed
11
13
  if (needsUnicode) {
12
14
  // Try compiling with 'u' flag only
@@ -42,5 +42,9 @@ export const whatIs = (what: unknown): WHAT_IS => {
42
42
  };
43
43
 
44
44
  export function isObject(value: unknown): value is Record<any, any> {
45
- return whatIs(value) === 'object';
45
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
46
+ }
47
+
48
+ export function isInteger(value: unknown): value is number {
49
+ return typeof value === 'number' && Number.isFinite(value) && value % 1 === 0;
46
50
  }
@@ -1,12 +1,12 @@
1
1
  import type { ValidateError } from './errors.js';
2
2
  import type { FormatValidatorFn } from './format-validators.js';
3
- import type { JsonSchemaVersion } from './json-schema.js';
3
+ import type { JsonSchema, JsonSchemaInternal, JsonSchemaVersion } from './json-schema-versions.js';
4
4
  import type { SchemaErrorDetail } from './report.js';
5
5
  import type { ZSchemaOptions } from './z-schema-options.js';
6
6
 
7
7
  import { type Errors, getValidateError } from './errors.js';
8
8
  import { getSupportedFormats } from './format-validators.js';
9
- import { type JsonSchema, type JsonSchemaInternal, VERSION_SCHEMA_URL_MAPPING } from './json-schema.js';
9
+ import { VERSION_SCHEMA_URL_MAPPING } from './json-schema-versions.js';
10
10
  import { validate as validateJson } from './json-validation.js';
11
11
  import { Report } from './report.js';
12
12
  import { SchemaCache } from './schema-cache.js';
@@ -16,7 +16,7 @@ import { deepClone } from './utils/clone.js';
16
16
  import { get, sortedKeys } from './utils/json.js';
17
17
  import { copyProp } from './utils/properties.js';
18
18
  import { getRemotePath } from './utils/uri.js';
19
- import { whatIs } from './utils/what-is.js';
19
+ import { isObject, whatIs } from './utils/what-is.js';
20
20
  import { defaultOptions, normalizeOptions } from './z-schema-options.js';
21
21
 
22
22
  export interface ValidateOptions {
@@ -74,10 +74,9 @@ export class ZSchemaBase {
74
74
 
75
75
  this.validateOptions = options;
76
76
 
77
- const schemaType = whatIs(schema);
78
- if (schemaType !== 'string' && schemaType !== 'object') {
77
+ if (typeof schema !== 'string' && typeof schema !== 'boolean' && !isObject(schema)) {
79
78
  const e = new Error(
80
- 'Invalid .validate call - schema must be a string or object but ' + schemaType + ' was passed!'
79
+ 'Invalid .validate call - schema must be a string or object but ' + whatIs(schema) + ' was passed!'
81
80
  );
82
81
  if (callback) {
83
82
  setTimeout(function () {
@@ -1,7 +1,7 @@
1
1
  import type { FormatValidatorFn } from './format-validators.js';
2
- import type { JsonSchemaVersion } from './json-schema.js';
3
2
  import type { Report } from './report.js';
4
3
 
4
+ import { CURRENT_DEFAULT_SCHEMA_VERSION, type JsonSchemaVersion } from './json-schema-versions.js';
5
5
  import { shallowClone } from './utils/clone.js';
6
6
 
7
7
  export interface ZSchemaOptions {
@@ -32,7 +32,8 @@ export interface ZSchemaOptions {
32
32
  }
33
33
 
34
34
  export const defaultOptions: ZSchemaOptions = {
35
- version: 'draft-04',
35
+ // default version to validate against
36
+ version: CURRENT_DEFAULT_SCHEMA_VERSION,
36
37
  // default timeout for all async tasks
37
38
  asyncTimeout: 2000,
38
39
  // force additionalProperties and additionalItems to be defined on "object" and "array" types
@@ -1,4 +1,4 @@
1
- import type { JsonSchema } from './json-schema.js';
1
+ import type { JsonSchema } from './json-schema-versions.js';
2
2
 
3
3
  // a sync function that loads schemas for future use, for example from schemas directory, during server startup
4
4
  export type SchemaReader = (uri: string) => JsonSchema;
@@ -0,0 +1,38 @@
1
+ // import schemas so they don't have to be downloaded for validation purposes
2
+ import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
3
+ import type { ZSchemaOptions } from './z-schema-options.js';
4
+
5
+ import { SchemaCache } from './schema-cache.js';
6
+ import { normalizeOptions } from './z-schema-options.js';
7
+
8
+ import _Draft4HyperSchema from './schemas/draft-04-hyper-schema.json' with { type: 'json' };
9
+ import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
10
+ import _Draft6HyperSchema from './schemas/draft-06-hyper-schema.json' with { type: 'json' };
11
+ import _Draft6Links from './schemas/draft-06-links.json' with { type: 'json' };
12
+ import _Draft6Schema from './schemas/draft-06-schema.json' with { type: 'json' };
13
+
14
+ const Draft4Schema: JsonSchema = _Draft4Schema;
15
+ const Draft4HyperSchema: JsonSchema = _Draft4HyperSchema;
16
+ const Draft6Schema: JsonSchema = _Draft6Schema;
17
+ const Draft6HyperSchema: JsonSchema = _Draft6HyperSchema;
18
+ const Draft6Links: JsonSchema = _Draft6Links;
19
+
20
+ const registerRemoteReference = (uri: string, schema: JsonSchema, validationOptions?: ZSchemaOptions) => {
21
+ const preparedSchema = schema as JsonSchemaInternal;
22
+
23
+ if (!preparedSchema.id) {
24
+ preparedSchema.id = uri;
25
+ }
26
+
27
+ if (validationOptions) {
28
+ preparedSchema.__$validationOptions = normalizeOptions(validationOptions);
29
+ }
30
+
31
+ SchemaCache.cacheSchemaByUri(uri, preparedSchema);
32
+ };
33
+
34
+ registerRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, { version: 'none' });
35
+ registerRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, { version: 'none' });
36
+ registerRemoteReference('http://json-schema.org/draft-06/schema', Draft6Schema, { version: 'none' });
37
+ registerRemoteReference('http://json-schema.org/draft-06/hyper-schema', Draft6HyperSchema, { version: 'none' });
38
+ registerRemoteReference('http://json-schema.org/draft-06/links', Draft6Links, { version: 'none' });
package/src/z-schema.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import type { ValidateError } from './errors.js';
2
2
  import type { FormatValidatorFn } from './format-validators.js';
3
- import type { JsonSchema, JsonSchemaInternal } from './json-schema.js';
3
+ import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
4
4
  import type { ValidateOptions, ValidateResponse } from './z-schema-base.js';
5
5
  import type { ZSchemaOptions } from './z-schema-options.js';
6
6
  import type { SchemaReader } from './z-schema-reader.js';
7
7
 
8
+ import './z-schema-versions.js';
9
+
8
10
  import { getRegisteredFormats, registerFormat, unregisterFormat } from './format-validators.js';
9
11
  import { SchemaCache } from './schema-cache.js';
10
12
  import { deepClone } from './utils/clone.js';
@@ -13,11 +15,12 @@ import { ZSchemaBase } from './z-schema-base.js';
13
15
  import { defaultOptions, normalizeOptions } from './z-schema-options.js';
14
16
  import { getSchemaReader, setSchemaReader } from './z-schema-reader.js';
15
17
 
16
- // import schemas so they don't have to be downloaded for validation purposes
17
- import _Draft4HyperSchema from './schemas/draft-04-hyper-schema.json' with { type: 'json' };
18
- import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
19
-
20
18
  export class ZSchema extends ZSchemaBase {
19
+ /** @deprecated Use ZSchema.create() instead. */
20
+ private constructor(options?: ZSchemaOptions) {
21
+ super(options);
22
+ }
23
+
21
24
  // ----- static methods start -----
22
25
 
23
26
  // class scoped format functions
@@ -85,14 +88,18 @@ export class ZSchema extends ZSchemaBase {
85
88
  delete options.safe;
86
89
  (options as any).__called_from_factory__ = true;
87
90
  if (isAsync && isSafe) {
91
+ // @ts-expect-error Factory can use private/deprecated constructor
88
92
  return new ZSchemaAsyncSafe(options);
89
93
  }
90
94
  if (isAsync) {
95
+ // @ts-expect-error Factory can use private/deprecated constructor
91
96
  return new ZSchemaAsync(options);
92
97
  }
93
98
  if (isSafe) {
99
+ // @ts-expect-error Factory can use private/deprecated constructor
94
100
  return new ZSchemaSafe(options);
95
101
  }
102
+ // Factory can use private/deprecated constructor
96
103
  return new ZSchema(options);
97
104
  }
98
105
 
@@ -148,6 +155,11 @@ export class ZSchema extends ZSchemaBase {
148
155
  }
149
156
 
150
157
  export class ZSchemaSafe extends ZSchemaBase {
158
+ /** @deprecated Use ZSchema.create() instead. */
159
+ private constructor(options?: ZSchemaOptions) {
160
+ super(options);
161
+ }
162
+
151
163
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): ValidateResponse {
152
164
  try {
153
165
  this._validate(json, schema, options);
@@ -168,6 +180,11 @@ export class ZSchemaSafe extends ZSchemaBase {
168
180
  }
169
181
 
170
182
  export class ZSchemaAsync extends ZSchemaBase {
183
+ /** @deprecated Use ZSchema.create() instead. */
184
+ private constructor(options?: ZSchemaOptions) {
185
+ super(options);
186
+ }
187
+
171
188
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): Promise<true> {
172
189
  return new Promise((resolve, reject) => {
173
190
  try {
@@ -184,6 +201,11 @@ export class ZSchemaAsync extends ZSchemaBase {
184
201
  }
185
202
 
186
203
  export class ZSchemaAsyncSafe extends ZSchemaBase {
204
+ /** @deprecated Use ZSchema.create() instead. */
205
+ private constructor(options?: ZSchemaOptions) {
206
+ super(options);
207
+ }
208
+
187
209
  validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions = {}): Promise<ValidateResponse> {
188
210
  return new Promise((resolve) => {
189
211
  try {
@@ -205,9 +227,3 @@ export class ZSchemaAsyncSafe extends ZSchemaBase {
205
227
  }
206
228
  }
207
229
  }
208
-
209
- const Draft4Schema: JsonSchema = _Draft4Schema;
210
- const Draft4HyperSchema: JsonSchema = _Draft4HyperSchema;
211
-
212
- ZSchema.setRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, { version: 'none' });
213
- ZSchema.setRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, { version: 'none' });