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.
- package/README.md +123 -191
- package/cjs/index.d.ts +33 -9
- package/cjs/index.js +4799 -3984
- package/dist/errors.js +5 -0
- package/dist/format-validators.js +65 -0
- package/dist/json-schema-versions.js +5 -0
- package/dist/json-schema.js +11 -4
- package/dist/json-validation.js +151 -10
- package/dist/report.js +2 -3
- package/dist/schema-cache.js +23 -2
- package/dist/schema-compiler.js +25 -10
- package/dist/schema-validator.js +66 -45
- package/dist/schemas/draft-06-hyper-schema.json +132 -0
- package/dist/schemas/draft-06-links.json +43 -0
- package/dist/schemas/draft-06-schema.json +155 -0
- package/dist/types/errors.d.ts +4 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/json-schema-versions.d.ts +23 -0
- package/dist/types/json-schema.d.ts +5 -9
- package/dist/types/json-validation.d.ts +3 -3
- package/dist/types/report.d.ts +3 -3
- package/dist/types/schema-cache.d.ts +1 -1
- package/dist/types/schema-compiler.d.ts +1 -1
- package/dist/types/schema-validator.d.ts +1 -1
- package/dist/types/utils/what-is.d.ts +1 -0
- package/dist/types/z-schema-base.d.ts +1 -1
- package/dist/types/z-schema-options.d.ts +1 -1
- package/dist/types/z-schema-reader.d.ts +1 -1
- package/dist/types/z-schema-versions.d.ts +1 -0
- package/dist/types/z-schema.d.ts +10 -1
- package/dist/utils/schema-regex.js +4 -3
- package/dist/utils/what-is.js +4 -1
- package/dist/z-schema-base.js +4 -5
- package/dist/z-schema-options.js +3 -1
- package/dist/z-schema-versions.js +27 -0
- package/dist/z-schema.js +21 -7
- package/package.json +2 -2
- package/src/errors.ts +6 -0
- package/src/format-validators.ts +65 -0
- package/src/index.ts +2 -1
- package/src/json-schema-versions.ts +34 -0
- package/src/json-schema.ts +22 -16
- package/src/json-validation.ts +183 -13
- package/src/report.ts +5 -6
- package/src/schema-cache.ts +25 -3
- package/src/schema-compiler.ts +25 -11
- package/src/schema-validator.ts +128 -62
- package/src/schemas/draft-06-hyper-schema.json +133 -0
- package/src/schemas/draft-06-links.json +43 -0
- package/src/schemas/draft-06-schema.json +155 -0
- package/src/utils/schema-regex.ts +5 -3
- package/src/utils/what-is.ts +5 -1
- package/src/z-schema-base.ts +5 -6
- package/src/z-schema-options.ts +3 -2
- package/src/z-schema-reader.ts +1 -1
- package/src/z-schema-versions.ts +38 -0
- package/src/z-schema.ts +27 -11
- package/umd/ZSchema.js +5100 -4285
- package/umd/ZSchema.min.js +1 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
|
|
1
2
|
import type { Reference } from './schema-compiler.js';
|
|
2
3
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
3
|
-
export
|
|
4
|
-
export declare const VERSION_SCHEMA_URL_MAPPING: Record<JsonSchemaVersion, string>;
|
|
5
|
-
export interface JsonSchema {
|
|
4
|
+
export interface JsonSchemaCommon {
|
|
6
5
|
$ref?: string;
|
|
7
|
-
id?: string;
|
|
8
6
|
$schema?: string;
|
|
7
|
+
id?: string;
|
|
9
8
|
title?: string;
|
|
10
9
|
description?: string;
|
|
11
10
|
default?: unknown;
|
|
@@ -13,12 +12,9 @@ export interface JsonSchema {
|
|
|
13
12
|
type?: string | string[];
|
|
14
13
|
properties?: Record<string, JsonSchema>;
|
|
15
14
|
patternProperties?: Record<string, JsonSchema>;
|
|
16
|
-
dependencies?: Record<string, string[]>;
|
|
17
15
|
multipleOf?: number;
|
|
18
16
|
minimum?: number;
|
|
19
|
-
exclusiveMinimum?: boolean;
|
|
20
17
|
maximum?: number;
|
|
21
|
-
exclusiveMaximum?: boolean;
|
|
22
18
|
minLength?: number;
|
|
23
19
|
maxLength?: number;
|
|
24
20
|
pattern?: string;
|
|
@@ -31,6 +27,7 @@ export interface JsonSchema {
|
|
|
31
27
|
maxProperties?: number;
|
|
32
28
|
required?: string[];
|
|
33
29
|
additionalProperties?: boolean | JsonSchema;
|
|
30
|
+
dependencies?: Record<string, string[] | JsonSchema>;
|
|
34
31
|
enum?: Array<unknown>;
|
|
35
32
|
format?: string;
|
|
36
33
|
allOf?: JsonSchema[];
|
|
@@ -48,6 +45,5 @@ export interface ZSchemaInternalProperties {
|
|
|
48
45
|
__$validationOptions?: ZSchemaOptions;
|
|
49
46
|
__$visited?: boolean;
|
|
50
47
|
}
|
|
51
|
-
export
|
|
52
|
-
}
|
|
48
|
+
export declare const getId: (schema: JsonSchemaInternal) => string | undefined;
|
|
53
49
|
export declare const findId: (schema: JsonSchemaInternal, id: string) => JsonSchemaInternal | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
1
|
+
import type { JsonSchema, JsonSchemaAll, JsonSchemaInternal } from './json-schema-versions.js';
|
|
2
2
|
import type { ZSchemaBase } from './z-schema-base.js';
|
|
3
3
|
import { Report } from './report.js';
|
|
4
4
|
type JsonValidatorFn = (this: ZSchemaBase, report: Report, schema: JsonSchema, json: unknown) => void;
|
|
5
|
-
export declare const JsonValidators: Record<keyof
|
|
6
|
-
export declare function validate(this: ZSchemaBase, report: Report, schema: JsonSchemaInternal, json: unknown): boolean;
|
|
5
|
+
export declare const JsonValidators: Record<keyof JsonSchemaAll, JsonValidatorFn>;
|
|
6
|
+
export declare function validate(this: ZSchemaBase, report: Report, schema: boolean | JsonSchemaInternal, json: unknown): boolean;
|
|
7
7
|
export {};
|
package/dist/types/report.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ErrorCode, ErrorParam } from './errors.js';
|
|
2
|
-
import type { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
2
|
+
import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
|
|
3
3
|
import type { ValidateCallback, ValidateOptions } from './z-schema-base.js';
|
|
4
4
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
5
5
|
export interface SchemaErrorDetail {
|
|
@@ -77,8 +77,8 @@ export declare class Report {
|
|
|
77
77
|
getSchemaPath(): Array<string | number>;
|
|
78
78
|
getSchemaId(): string | undefined;
|
|
79
79
|
hasError(errCode: string, errParams: Array<any>): boolean;
|
|
80
|
-
addError(errCode: ErrorCode, errParams?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema, keyword?: keyof JsonSchema): void;
|
|
80
|
+
addError(errCode: ErrorCode, errParams?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema | boolean, keyword?: keyof JsonSchema): void;
|
|
81
81
|
getJson(): unknown;
|
|
82
|
-
addCustomError(errorCode: ErrorCode, errorMessage: string, params?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema, keyword?: keyof JsonSchema): void;
|
|
82
|
+
addCustomError(errorCode: ErrorCode, errorMessage: string, params?: ErrorParam[], subReports?: Report | Report[], schema?: JsonSchema | boolean, keyword?: keyof JsonSchema): void;
|
|
83
83
|
}
|
|
84
84
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonSchema, JsonSchemaInternal } from './json-schema.js';
|
|
1
|
+
import type { JsonSchema, JsonSchemaInternal } from './json-schema-versions.js';
|
|
2
2
|
import type { ZSchemaBase } from './z-schema-base.js';
|
|
3
3
|
import { Report } from './report.js';
|
|
4
4
|
export type SchemaCacheStorage = Record<string, JsonSchemaInternal>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type WHAT_IS = 'undefined' | 'null' | 'object' | 'array' | 'integer' | 'number' | 'string' | 'not-a-number' | 'unknown-number' | 'bigint' | 'boolean' | 'symbol' | 'function';
|
|
2
2
|
export declare const whatIs: (what: unknown) => WHAT_IS;
|
|
3
3
|
export declare function isObject(value: unknown): value is Record<any, any>;
|
|
4
|
+
export declare function isInteger(value: unknown): value is number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ValidateError } from './errors.js';
|
|
2
2
|
import type { FormatValidatorFn } from './format-validators.js';
|
|
3
|
+
import type { JsonSchema } from './json-schema-versions.js';
|
|
3
4
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
4
5
|
import { type Errors } from './errors.js';
|
|
5
|
-
import { type JsonSchema } from './json-schema.js';
|
|
6
6
|
import { SchemaCache } from './schema-cache.js';
|
|
7
7
|
import { SchemaCompiler } from './schema-compiler.js';
|
|
8
8
|
import { SchemaValidator } from './schema-validator.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
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';
|
|
3
|
+
import { type JsonSchemaVersion } from './json-schema-versions.js';
|
|
4
4
|
export interface ZSchemaOptions {
|
|
5
5
|
version?: JsonSchemaVersion | 'none';
|
|
6
6
|
asyncTimeout?: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonSchema } from './json-schema.js';
|
|
1
|
+
import type { JsonSchema } from './json-schema-versions.js';
|
|
2
2
|
export type SchemaReader = (uri: string) => JsonSchema;
|
|
3
3
|
export declare function getSchemaReader(): SchemaReader | undefined;
|
|
4
4
|
export declare function setSchemaReader(schemaReader: SchemaReader | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/z-schema.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { FormatValidatorFn } from './format-validators.js';
|
|
2
|
-
import type { JsonSchema } from './json-schema.js';
|
|
2
|
+
import type { JsonSchema } from './json-schema-versions.js';
|
|
3
3
|
import type { ValidateOptions, ValidateResponse } from './z-schema-base.js';
|
|
4
4
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
5
5
|
import type { SchemaReader } from './z-schema-reader.js';
|
|
6
|
+
import './z-schema-versions.js';
|
|
6
7
|
import { ZSchemaBase } from './z-schema-base.js';
|
|
7
8
|
export declare class ZSchema extends ZSchemaBase {
|
|
9
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
10
|
+
private constructor();
|
|
8
11
|
static registerFormat(name: string, validatorFunction: FormatValidatorFn): void;
|
|
9
12
|
static unregisterFormat(name: string): void;
|
|
10
13
|
static getRegisteredFormats(): string[];
|
|
@@ -33,14 +36,20 @@ export declare class ZSchema extends ZSchemaBase {
|
|
|
33
36
|
validateSchemaSafe(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse;
|
|
34
37
|
}
|
|
35
38
|
export declare class ZSchemaSafe extends ZSchemaBase {
|
|
39
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
40
|
+
private constructor();
|
|
36
41
|
validate(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): ValidateResponse;
|
|
37
42
|
validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse;
|
|
38
43
|
}
|
|
39
44
|
export declare class ZSchemaAsync extends ZSchemaBase {
|
|
45
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
46
|
+
private constructor();
|
|
40
47
|
validate(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): Promise<true>;
|
|
41
48
|
validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): true;
|
|
42
49
|
}
|
|
43
50
|
export declare class ZSchemaAsyncSafe extends ZSchemaBase {
|
|
51
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
52
|
+
private constructor();
|
|
44
53
|
validate(json: unknown, schema: JsonSchema | string, options?: ValidateOptions): Promise<ValidateResponse>;
|
|
45
54
|
validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): ValidateResponse;
|
|
46
55
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Shared regex compilation helper for JSON Schema patterns
|
|
2
2
|
// Returns { ok: true, value: RegExp } or { ok: false, error: { pattern, message } }
|
|
3
3
|
export function compileSchemaRegex(pattern) {
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const unicodePropertyEscape = /\\[pP]{/;
|
|
5
|
+
const nonBmpCharacter = /[\u{10000}-\u{10FFFF}]/u;
|
|
6
|
+
const surrogatePairEscape = /\\uD[89AB][0-9A-Fa-f]{2}\\uD[CDEF][0-9A-Fa-f]{2}/;
|
|
7
|
+
const needsUnicode = unicodePropertyEscape.test(pattern) || nonBmpCharacter.test(pattern) || surrogatePairEscape.test(pattern);
|
|
7
8
|
// Try compiling without 'u' flag if not needed
|
|
8
9
|
if (needsUnicode) {
|
|
9
10
|
// Try compiling with 'u' flag only
|
package/dist/utils/what-is.js
CHANGED
|
@@ -25,5 +25,8 @@ export const whatIs = (what) => {
|
|
|
25
25
|
return typeof what; // undefined, boolean, string, function
|
|
26
26
|
};
|
|
27
27
|
export function isObject(value) {
|
|
28
|
-
return
|
|
28
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
29
|
+
}
|
|
30
|
+
export function isInteger(value) {
|
|
31
|
+
return typeof value === 'number' && Number.isFinite(value) && value % 1 === 0;
|
|
29
32
|
}
|
package/dist/z-schema-base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getValidateError } from './errors.js';
|
|
2
2
|
import { getSupportedFormats } from './format-validators.js';
|
|
3
|
-
import { VERSION_SCHEMA_URL_MAPPING } from './json-schema.js';
|
|
3
|
+
import { VERSION_SCHEMA_URL_MAPPING } from './json-schema-versions.js';
|
|
4
4
|
import { validate as validateJson } from './json-validation.js';
|
|
5
5
|
import { Report } from './report.js';
|
|
6
6
|
import { SchemaCache } from './schema-cache.js';
|
|
@@ -10,7 +10,7 @@ import { deepClone } from './utils/clone.js';
|
|
|
10
10
|
import { get, sortedKeys } from './utils/json.js';
|
|
11
11
|
import { copyProp } from './utils/properties.js';
|
|
12
12
|
import { getRemotePath } from './utils/uri.js';
|
|
13
|
-
import { whatIs } from './utils/what-is.js';
|
|
13
|
+
import { isObject, whatIs } from './utils/what-is.js';
|
|
14
14
|
import { defaultOptions, normalizeOptions } from './z-schema-options.js';
|
|
15
15
|
export class ZSchemaBase {
|
|
16
16
|
scache;
|
|
@@ -42,9 +42,8 @@ export class ZSchemaBase {
|
|
|
42
42
|
options = {};
|
|
43
43
|
}
|
|
44
44
|
this.validateOptions = options;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const e = new Error('Invalid .validate call - schema must be a string or object but ' + schemaType + ' was passed!');
|
|
45
|
+
if (typeof schema !== 'string' && typeof schema !== 'boolean' && !isObject(schema)) {
|
|
46
|
+
const e = new Error('Invalid .validate call - schema must be a string or object but ' + whatIs(schema) + ' was passed!');
|
|
48
47
|
if (callback) {
|
|
49
48
|
setTimeout(function () {
|
|
50
49
|
callback(e, false);
|
package/dist/z-schema-options.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { CURRENT_DEFAULT_SCHEMA_VERSION } from './json-schema-versions.js';
|
|
1
2
|
import { shallowClone } from './utils/clone.js';
|
|
2
3
|
export const defaultOptions = {
|
|
3
|
-
version
|
|
4
|
+
// default version to validate against
|
|
5
|
+
version: CURRENT_DEFAULT_SCHEMA_VERSION,
|
|
4
6
|
// default timeout for all async tasks
|
|
5
7
|
asyncTimeout: 2000,
|
|
6
8
|
// force additionalProperties and additionalItems to be defined on "object" and "array" types
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SchemaCache } from './schema-cache.js';
|
|
2
|
+
import { normalizeOptions } from './z-schema-options.js';
|
|
3
|
+
import _Draft4HyperSchema from './schemas/draft-04-hyper-schema.json' with { type: 'json' };
|
|
4
|
+
import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
|
|
5
|
+
import _Draft6HyperSchema from './schemas/draft-06-hyper-schema.json' with { type: 'json' };
|
|
6
|
+
import _Draft6Links from './schemas/draft-06-links.json' with { type: 'json' };
|
|
7
|
+
import _Draft6Schema from './schemas/draft-06-schema.json' with { type: 'json' };
|
|
8
|
+
const Draft4Schema = _Draft4Schema;
|
|
9
|
+
const Draft4HyperSchema = _Draft4HyperSchema;
|
|
10
|
+
const Draft6Schema = _Draft6Schema;
|
|
11
|
+
const Draft6HyperSchema = _Draft6HyperSchema;
|
|
12
|
+
const Draft6Links = _Draft6Links;
|
|
13
|
+
const registerRemoteReference = (uri, schema, validationOptions) => {
|
|
14
|
+
const preparedSchema = schema;
|
|
15
|
+
if (!preparedSchema.id) {
|
|
16
|
+
preparedSchema.id = uri;
|
|
17
|
+
}
|
|
18
|
+
if (validationOptions) {
|
|
19
|
+
preparedSchema.__$validationOptions = normalizeOptions(validationOptions);
|
|
20
|
+
}
|
|
21
|
+
SchemaCache.cacheSchemaByUri(uri, preparedSchema);
|
|
22
|
+
};
|
|
23
|
+
registerRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, { version: 'none' });
|
|
24
|
+
registerRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, { version: 'none' });
|
|
25
|
+
registerRemoteReference('http://json-schema.org/draft-06/schema', Draft6Schema, { version: 'none' });
|
|
26
|
+
registerRemoteReference('http://json-schema.org/draft-06/hyper-schema', Draft6HyperSchema, { version: 'none' });
|
|
27
|
+
registerRemoteReference('http://json-schema.org/draft-06/links', Draft6Links, { version: 'none' });
|
package/dist/z-schema.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import './z-schema-versions.js';
|
|
1
2
|
import { getRegisteredFormats, registerFormat, unregisterFormat } from './format-validators.js';
|
|
2
3
|
import { SchemaCache } from './schema-cache.js';
|
|
3
4
|
import { deepClone } from './utils/clone.js';
|
|
@@ -5,10 +6,11 @@ import { jsonSymbol, schemaSymbol } from './utils/symbols.js';
|
|
|
5
6
|
import { ZSchemaBase } from './z-schema-base.js';
|
|
6
7
|
import { defaultOptions, normalizeOptions } from './z-schema-options.js';
|
|
7
8
|
import { getSchemaReader, setSchemaReader } from './z-schema-reader.js';
|
|
8
|
-
// import schemas so they don't have to be downloaded for validation purposes
|
|
9
|
-
import _Draft4HyperSchema from './schemas/draft-04-hyper-schema.json' with { type: 'json' };
|
|
10
|
-
import _Draft4Schema from './schemas/draft-04-schema.json' with { type: 'json' };
|
|
11
9
|
export class ZSchema extends ZSchemaBase {
|
|
10
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
11
|
+
constructor(options) {
|
|
12
|
+
super(options);
|
|
13
|
+
}
|
|
12
14
|
// ----- static methods start -----
|
|
13
15
|
// class scoped format functions
|
|
14
16
|
static registerFormat(name, validatorFunction) {
|
|
@@ -55,14 +57,18 @@ export class ZSchema extends ZSchemaBase {
|
|
|
55
57
|
delete options.safe;
|
|
56
58
|
options.__called_from_factory__ = true;
|
|
57
59
|
if (isAsync && isSafe) {
|
|
60
|
+
// @ts-expect-error Factory can use private/deprecated constructor
|
|
58
61
|
return new ZSchemaAsyncSafe(options);
|
|
59
62
|
}
|
|
60
63
|
if (isAsync) {
|
|
64
|
+
// @ts-expect-error Factory can use private/deprecated constructor
|
|
61
65
|
return new ZSchemaAsync(options);
|
|
62
66
|
}
|
|
63
67
|
if (isSafe) {
|
|
68
|
+
// @ts-expect-error Factory can use private/deprecated constructor
|
|
64
69
|
return new ZSchemaSafe(options);
|
|
65
70
|
}
|
|
71
|
+
// Factory can use private/deprecated constructor
|
|
66
72
|
return new ZSchema(options);
|
|
67
73
|
}
|
|
68
74
|
validate(json, schema, options = {}) {
|
|
@@ -113,6 +119,10 @@ export class ZSchema extends ZSchemaBase {
|
|
|
113
119
|
}
|
|
114
120
|
}
|
|
115
121
|
export class ZSchemaSafe extends ZSchemaBase {
|
|
122
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
123
|
+
constructor(options) {
|
|
124
|
+
super(options);
|
|
125
|
+
}
|
|
116
126
|
validate(json, schema, options = {}) {
|
|
117
127
|
try {
|
|
118
128
|
this._validate(json, schema, options);
|
|
@@ -133,6 +143,10 @@ export class ZSchemaSafe extends ZSchemaBase {
|
|
|
133
143
|
}
|
|
134
144
|
}
|
|
135
145
|
export class ZSchemaAsync extends ZSchemaBase {
|
|
146
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
147
|
+
constructor(options) {
|
|
148
|
+
super(options);
|
|
149
|
+
}
|
|
136
150
|
validate(json, schema, options = {}) {
|
|
137
151
|
return new Promise((resolve, reject) => {
|
|
138
152
|
try {
|
|
@@ -148,6 +162,10 @@ export class ZSchemaAsync extends ZSchemaBase {
|
|
|
148
162
|
}
|
|
149
163
|
}
|
|
150
164
|
export class ZSchemaAsyncSafe extends ZSchemaBase {
|
|
165
|
+
/** @deprecated Use ZSchema.create() instead. */
|
|
166
|
+
constructor(options) {
|
|
167
|
+
super(options);
|
|
168
|
+
}
|
|
151
169
|
validate(json, schema, options = {}) {
|
|
152
170
|
return new Promise((resolve) => {
|
|
153
171
|
try {
|
|
@@ -170,7 +188,3 @@ export class ZSchemaAsyncSafe extends ZSchemaBase {
|
|
|
170
188
|
}
|
|
171
189
|
}
|
|
172
190
|
}
|
|
173
|
-
const Draft4Schema = _Draft4Schema;
|
|
174
|
-
const Draft4HyperSchema = _Draft4HyperSchema;
|
|
175
|
-
ZSchema.setRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, { version: 'none' });
|
|
176
|
-
ZSchema.setRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, { version: 'none' });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "z-schema",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.0.0"
|
|
6
6
|
},
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"test:coverage": "vitest run --coverage",
|
|
68
68
|
"test:node": "vitest run --project node --silent=false",
|
|
69
69
|
"test:browser": "vitest run --project browser --silent=false",
|
|
70
|
-
"test:sample": "npx vitest run --silent=false --hideSkippedTests --project node -t \"
|
|
70
|
+
"test:sample": "npx vitest run --silent=false --hideSkippedTests --project node -t \"draft6/exclusiveMinimum.json\""
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"validator": "^13.15.26"
|
package/src/errors.ts
CHANGED
|
@@ -59,6 +59,12 @@ export const Errors = {
|
|
|
59
59
|
ASYNC_TIMEOUT: '{0} asynchronous task(s) have timed out after {1} ms',
|
|
60
60
|
PARENT_SCHEMA_VALIDATION_FAILED: 'Schema failed to validate against its parent schema, see inner errors for details.',
|
|
61
61
|
REMOTE_NOT_VALID: "Remote reference didn't compile successfully: {0}",
|
|
62
|
+
|
|
63
|
+
// Draft-06 errors
|
|
64
|
+
SCHEMA_IS_FALSE: 'Boolean schema "false" is always invalid.',
|
|
65
|
+
CONST: 'Value does not match const: {0}',
|
|
66
|
+
CONTAINS: 'Array does not contain an item matching the schema',
|
|
67
|
+
PROPERTY_NAMES: 'Property name {0} does not match the propertyNames schema',
|
|
62
68
|
};
|
|
63
69
|
|
|
64
70
|
export class ValidateError extends Error {
|
package/src/format-validators.ts
CHANGED
|
@@ -200,6 +200,65 @@ const uriValidator: FormatValidatorFn = function (uri: unknown) {
|
|
|
200
200
|
return /^[a-zA-Z][a-zA-Z0-9+.-]*:[^"\\<>^{}^`| ]*$/.test(uri);
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
+
const uriReferenceValidator: FormatValidatorFn = (uri: unknown) => {
|
|
204
|
+
if (typeof uri !== 'string') return true;
|
|
205
|
+
// eslint-disable-next-line no-control-regex
|
|
206
|
+
if (/[^\x00-\x7F]/.test(uri)) return false;
|
|
207
|
+
// URI-reference allows relative URIs
|
|
208
|
+
return /^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^{}^`| ]*$/.test(uri);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const uriTemplateValidator: FormatValidatorFn = (uri: unknown) => {
|
|
212
|
+
if (typeof uri !== 'string') return true;
|
|
213
|
+
// URI template allows braces for expressions.
|
|
214
|
+
if (!/^([a-zA-Z][a-zA-Z0-9+.-]*:)?[^"\\<>^`| ]*$/.test(uri)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let inExpression = false;
|
|
219
|
+
for (let idx = 0; idx < uri.length; idx++) {
|
|
220
|
+
const ch = uri[idx];
|
|
221
|
+
if (ch === '{') {
|
|
222
|
+
if (inExpression) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
inExpression = true;
|
|
226
|
+
} else if (ch === '}') {
|
|
227
|
+
if (!inExpression) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
inExpression = false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return !inExpression;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const jsonPointerValidator: FormatValidatorFn = (pointer: unknown) => {
|
|
238
|
+
if (typeof pointer !== 'string') return true;
|
|
239
|
+
// JSON Pointer: empty, or a sequence of '/'-prefixed reference tokens.
|
|
240
|
+
// In each token, '~' must be escaped as '~0' or '~1'.
|
|
241
|
+
return pointer === '' || /^(?:\/(?:[^~]|~0|~1)*)+$/.test(pointer);
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const relativeJsonPointerValidator: FormatValidatorFn = (pointer: unknown) => {
|
|
245
|
+
if (typeof pointer !== 'string') return true;
|
|
246
|
+
// Relative JSON Pointer: number#path or empty
|
|
247
|
+
return /^\d+(#.*)?$/.test(pointer) || pointer === '';
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const timeValidator: FormatValidatorFn = (time: unknown) => {
|
|
251
|
+
if (typeof time !== 'string') return true;
|
|
252
|
+
// time: hh:mm:ss[.fraction]
|
|
253
|
+
return /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)(\.\d+)?$/.test(time);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const idnEmailValidator: FormatValidatorFn = (email: unknown) => {
|
|
257
|
+
if (typeof email !== 'string') return true;
|
|
258
|
+
// Simple email check, allowing international chars
|
|
259
|
+
return /^[^\s@]+@[^\s@]+$/.test(email);
|
|
260
|
+
};
|
|
261
|
+
|
|
203
262
|
export interface FormatValidatorsOptions {
|
|
204
263
|
strictUris?: boolean;
|
|
205
264
|
customFormats?: Record<string, FormatValidatorFn | null>;
|
|
@@ -216,6 +275,12 @@ const inbuiltValidators: Record<string, FormatValidatorFn> = {
|
|
|
216
275
|
regex: regexValidator,
|
|
217
276
|
uri: uriValidator,
|
|
218
277
|
'strict-uri': strictUriValidator,
|
|
278
|
+
'uri-reference': uriReferenceValidator,
|
|
279
|
+
'uri-template': uriTemplateValidator,
|
|
280
|
+
'json-pointer': jsonPointerValidator,
|
|
281
|
+
'relative-json-pointer': relativeJsonPointerValidator,
|
|
282
|
+
time: timeValidator,
|
|
283
|
+
'idn-email': idnEmailValidator,
|
|
219
284
|
} as const;
|
|
220
285
|
|
|
221
286
|
const customValidators: Record<string, FormatValidatorFn> = {};
|
package/src/index.ts
CHANGED
|
@@ -13,7 +13,8 @@ export {
|
|
|
13
13
|
registerFormat,
|
|
14
14
|
unregisterFormat,
|
|
15
15
|
} from './format-validators.js';
|
|
16
|
-
export type {
|
|
16
|
+
export type { JsonSchemaType } from './json-schema.js';
|
|
17
|
+
export type { JsonSchema } from './json-schema-versions.js';
|
|
17
18
|
export type { Report, SchemaErrorDetail } from './report.js';
|
|
18
19
|
export type { ZSchema, ZSchemaAsync, ZSchemaAsyncSafe, ZSchemaSafe } from './z-schema.js';
|
|
19
20
|
export { ValidateOptions, ValidateResponse } from './z-schema-base.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JsonSchemaCommon, ZSchemaInternalProperties } from './json-schema.js';
|
|
2
|
+
|
|
3
|
+
// TODO: currently unsupported 'draft-07', '2019-09', '2020-12'
|
|
4
|
+
export type JsonSchemaVersion = 'draft-04' | 'draft-06';
|
|
5
|
+
|
|
6
|
+
export const CURRENT_DEFAULT_SCHEMA_VERSION: JsonSchemaVersion = 'draft-06';
|
|
7
|
+
|
|
8
|
+
export const VERSION_SCHEMA_URL_MAPPING: Record<JsonSchemaVersion, string> = {
|
|
9
|
+
'draft-04': 'http://json-schema.org/draft-04/schema#',
|
|
10
|
+
'draft-06': 'http://json-schema.org/draft-06/schema#',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type JsonSchema = JsonSchemaDraft4 | JsonSchemaDraft6;
|
|
14
|
+
export type JsonSchemaAll = JsonSchemaDraft4 & JsonSchemaDraft6;
|
|
15
|
+
|
|
16
|
+
export type JsonSchemaInternal = JsonSchema & ZSchemaInternalProperties;
|
|
17
|
+
export type JsonSchemaInternalAll = JsonSchemaAll & ZSchemaInternalProperties;
|
|
18
|
+
export type JsonSchemaInternalD4 = JsonSchemaDraft4 & ZSchemaInternalProperties;
|
|
19
|
+
export type JsonSchemaInternalD6 = JsonSchemaDraft6 & ZSchemaInternalProperties;
|
|
20
|
+
|
|
21
|
+
export interface JsonSchemaDraft4 extends JsonSchemaCommon {
|
|
22
|
+
exclusiveMaximum?: boolean;
|
|
23
|
+
exclusiveMinimum?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface JsonSchemaDraft6 extends JsonSchemaCommon {
|
|
27
|
+
$id?: string;
|
|
28
|
+
examples?: unknown[];
|
|
29
|
+
const?: unknown;
|
|
30
|
+
contains?: JsonSchema;
|
|
31
|
+
propertyNames?: JsonSchema;
|
|
32
|
+
exclusiveMaximum?: number;
|
|
33
|
+
exclusiveMinimum?: number;
|
|
34
|
+
}
|
package/src/json-schema.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
JsonSchema,
|
|
3
|
+
JsonSchemaInternal,
|
|
4
|
+
JsonSchemaInternalD4,
|
|
5
|
+
JsonSchemaInternalD6,
|
|
6
|
+
} from './json-schema-versions.js';
|
|
1
7
|
import type { Reference } from './schema-compiler.js';
|
|
2
8
|
import type { ZSchemaOptions } from './z-schema-options.js';
|
|
3
9
|
|
|
4
10
|
import { isObject } from './utils/what-is.js';
|
|
5
11
|
|
|
6
|
-
//
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
export const VERSION_SCHEMA_URL_MAPPING: Record<JsonSchemaVersion, string> = {
|
|
10
|
-
'draft-04': 'http://json-schema.org/draft-04/schema#',
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export interface JsonSchema {
|
|
12
|
+
// common properties of all JSON Schema versions
|
|
13
|
+
export interface JsonSchemaCommon {
|
|
14
14
|
$ref?: string;
|
|
15
|
-
id?: string;
|
|
16
15
|
$schema?: string;
|
|
16
|
+
id?: string;
|
|
17
17
|
title?: string;
|
|
18
18
|
description?: string;
|
|
19
19
|
default?: unknown;
|
|
@@ -21,13 +21,9 @@ export interface JsonSchema {
|
|
|
21
21
|
type?: string | string[];
|
|
22
22
|
properties?: Record<string, JsonSchema>;
|
|
23
23
|
patternProperties?: Record<string, JsonSchema>;
|
|
24
|
-
dependencies?: Record<string, string[]>;
|
|
25
|
-
// properties
|
|
26
24
|
multipleOf?: number;
|
|
27
25
|
minimum?: number;
|
|
28
|
-
exclusiveMinimum?: boolean;
|
|
29
26
|
maximum?: number;
|
|
30
|
-
exclusiveMaximum?: boolean;
|
|
31
27
|
minLength?: number;
|
|
32
28
|
maxLength?: number;
|
|
33
29
|
pattern?: string;
|
|
@@ -40,6 +36,7 @@ export interface JsonSchema {
|
|
|
40
36
|
maxProperties?: number;
|
|
41
37
|
required?: string[];
|
|
42
38
|
additionalProperties?: boolean | JsonSchema;
|
|
39
|
+
dependencies?: Record<string, string[] | JsonSchema>;
|
|
43
40
|
enum?: Array<unknown>;
|
|
44
41
|
format?: string;
|
|
45
42
|
allOf?: JsonSchema[];
|
|
@@ -60,7 +57,15 @@ export interface ZSchemaInternalProperties {
|
|
|
60
57
|
__$visited?: boolean;
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
export
|
|
60
|
+
export const getId = (schema: JsonSchemaInternal) => {
|
|
61
|
+
if ((schema as JsonSchemaInternalD6).$id) {
|
|
62
|
+
return (schema as JsonSchemaInternalD6).$id;
|
|
63
|
+
}
|
|
64
|
+
if ((schema as JsonSchemaInternalD4).id) {
|
|
65
|
+
return (schema as JsonSchemaInternalD4).id;
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
};
|
|
64
69
|
|
|
65
70
|
export const findId = (schema: JsonSchemaInternal, id: string): JsonSchemaInternal | undefined => {
|
|
66
71
|
// process only arrays and objects
|
|
@@ -73,8 +78,9 @@ export const findId = (schema: JsonSchemaInternal, id: string): JsonSchemaIntern
|
|
|
73
78
|
return schema;
|
|
74
79
|
}
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
const schemaId = getId(schema);
|
|
82
|
+
if (schemaId) {
|
|
83
|
+
if (schemaId === id || (schemaId[0] === '#' && schemaId.substring(1) === id)) {
|
|
78
84
|
return schema;
|
|
79
85
|
}
|
|
80
86
|
}
|