z-schema 12.0.4 → 12.1.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/bin/z-schema +7 -2
- package/cjs/index.d.ts +541 -530
- package/cjs/index.js +3963 -7740
- package/dist/errors.d.mts +64 -0
- package/dist/errors.mjs +67 -0
- package/dist/format-validators.d.mts +14 -0
- package/dist/format-validators.mjs +261 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +7 -0
- package/dist/json-schema-versions.d.mts +137 -0
- package/dist/json-schema-versions.mjs +11 -0
- package/dist/json-schema.d.mts +61 -0
- package/dist/json-schema.mjs +53 -0
- package/dist/json-validation.mjs +441 -0
- package/dist/report.d.mts +97 -0
- package/dist/report.mjs +194 -0
- package/dist/schema-cache.d.mts +23 -0
- package/dist/schema-cache.mjs +144 -0
- package/dist/schema-compiler.d.mts +23 -0
- package/dist/schema-compiler.mjs +265 -0
- package/dist/schema-validator.d.mts +15 -0
- package/dist/schema-validator.mjs +446 -0
- package/dist/schemas/draft-04-schema.mjs +125 -0
- package/dist/schemas/draft-06-schema.mjs +126 -0
- package/dist/schemas/draft-07-schema.mjs +141 -0
- package/dist/schemas/draft-2019-09-meta-applicator.mjs +46 -0
- package/dist/schemas/draft-2019-09-meta-content.mjs +15 -0
- package/dist/schemas/draft-2019-09-meta-core.mjs +52 -0
- package/dist/schemas/draft-2019-09-meta-format.mjs +11 -0
- package/dist/schemas/draft-2019-09-meta-meta-data.mjs +31 -0
- package/dist/schemas/draft-2019-09-meta-validation.mjs +80 -0
- package/dist/schemas/draft-2019-09-schema.mjs +39 -0
- package/dist/schemas/draft-2020-12-meta-applicator.mjs +45 -0
- package/dist/schemas/draft-2020-12-meta-content.mjs +15 -0
- package/dist/schemas/draft-2020-12-meta-core.mjs +46 -0
- package/dist/schemas/draft-2020-12-meta-format-annotation.mjs +11 -0
- package/dist/schemas/draft-2020-12-meta-format-assertion.mjs +11 -0
- package/dist/schemas/draft-2020-12-meta-meta-data.mjs +31 -0
- package/dist/schemas/draft-2020-12-meta-unevaluated.mjs +14 -0
- package/dist/schemas/draft-2020-12-meta-validation.mjs +80 -0
- package/dist/schemas/draft-2020-12-schema.mjs +55 -0
- package/dist/utils/array.mjs +54 -0
- package/dist/utils/base64.mjs +21 -0
- package/dist/utils/clone.mjs +42 -0
- package/dist/utils/constants.mjs +16 -0
- package/dist/utils/date.mjs +19 -0
- package/dist/utils/hostname.mjs +73 -0
- package/dist/utils/json.mjs +34 -0
- package/dist/utils/properties.mjs +11 -0
- package/dist/utils/schema-regex.mjs +49 -0
- package/dist/utils/symbols.mjs +5 -0
- package/dist/utils/time.mjs +42 -0
- package/dist/utils/unicode.mjs +12 -0
- package/dist/utils/uri.mjs +12 -0
- package/dist/utils/what-is.mjs +23 -0
- package/dist/validation/array.mjs +57 -0
- package/dist/validation/combinators.mjs +62 -0
- package/dist/validation/numeric.mjs +38 -0
- package/dist/validation/object.mjs +109 -0
- package/dist/validation/ref.mjs +49 -0
- package/dist/validation/shared.mjs +97 -0
- package/dist/validation/string.mjs +88 -0
- package/dist/validation/type.mjs +32 -0
- package/dist/z-schema-base.d.mts +85 -0
- package/dist/z-schema-base.mjs +230 -0
- package/dist/z-schema-options.d.mts +35 -0
- package/dist/z-schema-options.mjs +55 -0
- package/dist/z-schema-reader.d.mts +6 -0
- package/dist/z-schema-reader.mjs +10 -0
- package/dist/z-schema-versions.mjs +67 -0
- package/dist/z-schema.d.mts +193 -0
- package/dist/z-schema.mjs +300 -0
- package/package.json +49 -64
- package/src/index.ts +3 -3
- package/src/schema-compiler.ts +30 -10
- package/src/schema-validator.ts +1 -1
- package/src/utils/schema-regex.ts +13 -2
- package/src/z-schema-base.ts +1 -1
- package/src/z-schema-versions.ts +1 -2
- package/src/z-schema.ts +0 -1
- package/umd/ZSchema.js +5934 -8110
- package/umd/ZSchema.min.js +2 -1
- package/dist/errors.js +0 -72
- package/dist/format-validators.js +0 -392
- package/dist/index.js +0 -5
- package/dist/json-schema-versions.js +0 -8
- package/dist/json-schema.js +0 -84
- package/dist/json-validation.js +0 -728
- package/dist/package.json +0 -3
- package/dist/report.js +0 -265
- package/dist/schema-cache.js +0 -211
- package/dist/schema-compiler.js +0 -415
- package/dist/schema-validator.js +0 -721
- package/dist/schemas/draft-04-schema.json +0 -149
- package/dist/schemas/draft-06-schema.json +0 -155
- package/dist/schemas/draft-07-schema.json +0 -172
- package/dist/schemas/draft-2019-09-meta-applicator.json +0 -52
- package/dist/schemas/draft-2019-09-meta-content.json +0 -12
- package/dist/schemas/draft-2019-09-meta-core.json +0 -53
- package/dist/schemas/draft-2019-09-meta-format.json +0 -10
- package/dist/schemas/draft-2019-09-meta-meta-data.json +0 -32
- package/dist/schemas/draft-2019-09-meta-validation.json +0 -94
- package/dist/schemas/draft-2019-09-schema.json +0 -41
- package/dist/schemas/draft-2020-12-meta-applicator.json +0 -44
- package/dist/schemas/draft-2020-12-meta-content.json +0 -12
- package/dist/schemas/draft-2020-12-meta-core.json +0 -47
- package/dist/schemas/draft-2020-12-meta-format-annotation.json +0 -10
- package/dist/schemas/draft-2020-12-meta-format-assertion.json +0 -10
- package/dist/schemas/draft-2020-12-meta-meta-data.json +0 -32
- package/dist/schemas/draft-2020-12-meta-unevaluated.json +0 -11
- package/dist/schemas/draft-2020-12-meta-validation.json +0 -94
- package/dist/schemas/draft-2020-12-schema.json +0 -57
- package/dist/types/errors.d.ts +0 -64
- package/dist/types/format-validators.d.ts +0 -11
- package/dist/types/index.d.ts +0 -14
- package/dist/types/json-schema-versions.d.ts +0 -142
- package/dist/types/json-schema.d.ts +0 -66
- package/dist/types/json-validation.d.ts +0 -6
- package/dist/types/report.d.ts +0 -94
- package/dist/types/schema-cache.d.ts +0 -27
- package/dist/types/schema-compiler.d.ts +0 -31
- package/dist/types/schema-validator.d.ts +0 -10
- package/dist/types/utils/array.d.ts +0 -9
- package/dist/types/utils/base64.d.ts +0 -2
- package/dist/types/utils/clone.d.ts +0 -2
- package/dist/types/utils/constants.d.ts +0 -19
- package/dist/types/utils/date.d.ts +0 -1
- package/dist/types/utils/hostname.d.ts +0 -2
- package/dist/types/utils/json.d.ts +0 -9
- package/dist/types/utils/properties.d.ts +0 -1
- package/dist/types/utils/schema-regex.d.ts +0 -10
- package/dist/types/utils/symbols.d.ts +0 -2
- package/dist/types/utils/time.d.ts +0 -12
- package/dist/types/utils/unicode.d.ts +0 -5
- package/dist/types/utils/uri.d.ts +0 -4
- package/dist/types/utils/what-is.d.ts +0 -4
- package/dist/types/validation/array.d.ts +0 -12
- package/dist/types/validation/combinators.d.ts +0 -10
- package/dist/types/validation/numeric.d.ts +0 -8
- package/dist/types/validation/object.d.ts +0 -13
- package/dist/types/validation/ref.d.ts +0 -11
- package/dist/types/validation/shared.d.ts +0 -26
- package/dist/types/validation/string.d.ts +0 -9
- package/dist/types/validation/type.d.ts +0 -6
- package/dist/types/z-schema-base.d.ts +0 -87
- package/dist/types/z-schema-options.d.ts +0 -35
- package/dist/types/z-schema-reader.d.ts +0 -4
- package/dist/types/z-schema-versions.d.ts +0 -1
- package/dist/types/z-schema.d.ts +0 -191
- package/dist/utils/array.js +0 -69
- package/dist/utils/base64.js +0 -29
- package/dist/utils/clone.js +0 -59
- package/dist/utils/constants.js +0 -19
- package/dist/utils/date.js +0 -21
- package/dist/utils/hostname.js +0 -146
- package/dist/utils/json.js +0 -70
- package/dist/utils/properties.js +0 -10
- package/dist/utils/schema-regex.js +0 -52
- package/dist/utils/symbols.js +0 -2
- package/dist/utils/time.js +0 -50
- package/dist/utils/unicode.js +0 -12
- package/dist/utils/uri.js +0 -15
- package/dist/utils/what-is.js +0 -32
- package/dist/validation/array.js +0 -127
- package/dist/validation/combinators.js +0 -106
- package/dist/validation/numeric.js +0 -97
- package/dist/validation/object.js +0 -237
- package/dist/validation/ref.js +0 -70
- package/dist/validation/shared.js +0 -136
- package/dist/validation/string.js +0 -170
- package/dist/validation/type.js +0 -55
- package/dist/z-schema-base.js +0 -286
- package/dist/z-schema-options.js +0 -99
- package/dist/z-schema-reader.js +0 -7
- package/dist/z-schema-versions.js +0 -110
- package/dist/z-schema.js +0 -287
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isUniqueArray } from "../utils/array.mjs";
|
|
2
|
+
import { cacheValidationResult, deferOrRunSync, shouldSkipValidate } from "./shared.mjs";
|
|
3
|
+
//#region src/validation/array.ts
|
|
4
|
+
function additionalItemsValidator(report, schema, json) {
|
|
5
|
+
if (shouldSkipValidate(this.validateOptions, ["ARRAY_ADDITIONAL_ITEMS"])) return;
|
|
6
|
+
if (!Array.isArray(json)) return;
|
|
7
|
+
if (schema.additionalItems === false && Array.isArray(schema.items)) {
|
|
8
|
+
if (json.length > schema.items.length) report.addError("ARRAY_ADDITIONAL_ITEMS", void 0, void 0, schema, "additionalItems");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function itemsValidator() {}
|
|
12
|
+
function prefixItemsValidator() {}
|
|
13
|
+
function maxItemsValidator(report, schema, json) {
|
|
14
|
+
if (shouldSkipValidate(this.validateOptions, ["ARRAY_LENGTH_LONG"])) return;
|
|
15
|
+
if (!Array.isArray(json)) return;
|
|
16
|
+
if (json.length > schema.maxItems) report.addError("ARRAY_LENGTH_LONG", [json.length, schema.maxItems], void 0, schema, "maxItems");
|
|
17
|
+
}
|
|
18
|
+
function minItemsValidator(report, schema, json) {
|
|
19
|
+
if (shouldSkipValidate(this.validateOptions, ["ARRAY_LENGTH_SHORT"])) return;
|
|
20
|
+
if (!Array.isArray(json)) return;
|
|
21
|
+
if (json.length < schema.minItems) report.addError("ARRAY_LENGTH_SHORT", [json.length, schema.minItems], void 0, schema, "minItems");
|
|
22
|
+
}
|
|
23
|
+
function uniqueItemsValidator(report, schema, json) {
|
|
24
|
+
if (shouldSkipValidate(this.validateOptions, ["ARRAY_UNIQUE"])) return;
|
|
25
|
+
if (!Array.isArray(json)) return;
|
|
26
|
+
if (schema.uniqueItems === true) {
|
|
27
|
+
const matches = [];
|
|
28
|
+
if (isUniqueArray(json, matches, this.options.maxRecursionDepth) === false) report.addError("ARRAY_UNIQUE", matches, void 0, schema, "uniqueItems");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function containsValidator(report, schema, json) {
|
|
32
|
+
if (shouldSkipValidate(this.validateOptions, ["CONTAINS"])) return;
|
|
33
|
+
if (!Array.isArray(json)) return;
|
|
34
|
+
const containsSchema = schema.contains;
|
|
35
|
+
if (containsSchema === void 0) return;
|
|
36
|
+
const Report_ = report.constructor;
|
|
37
|
+
const subReports = [];
|
|
38
|
+
for (let idx = 0; idx < json.length; idx++) {
|
|
39
|
+
const subReport = new Report_(report);
|
|
40
|
+
subReports.push(subReport);
|
|
41
|
+
this._jsonValidate(subReport, containsSchema, json[idx]);
|
|
42
|
+
cacheValidationResult(report, containsSchema, json[idx], subReport.errors.length === 0);
|
|
43
|
+
}
|
|
44
|
+
const addContainsErrorIfNeeded = () => {
|
|
45
|
+
let matchingItems = 0;
|
|
46
|
+
for (const subReport of subReports) if (subReport.errors.length === 0) matchingItems += 1;
|
|
47
|
+
const supportsContainsBounds = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
48
|
+
const minContains = supportsContainsBounds && typeof schema.minContains === "number" ? schema.minContains ?? 1 : 1;
|
|
49
|
+
const maxContains = supportsContainsBounds && typeof schema.maxContains === "number" ? schema.maxContains : void 0;
|
|
50
|
+
if (!(matchingItems >= minContains) || !(maxContains === void 0 || matchingItems <= maxContains)) report.addError("CONTAINS", void 0, subReports, schema, void 0);
|
|
51
|
+
};
|
|
52
|
+
deferOrRunSync(report, subReports, addContainsErrorIfNeeded);
|
|
53
|
+
}
|
|
54
|
+
function maxContainsValidator() {}
|
|
55
|
+
function minContainsValidator() {}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { additionalItemsValidator, containsValidator, itemsValidator, maxContainsValidator, maxItemsValidator, minContainsValidator, minItemsValidator, prefixItemsValidator, uniqueItemsValidator };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Report } from "../report.mjs";
|
|
2
|
+
import { cacheValidationResult, deferOrRunSync } from "./shared.mjs";
|
|
3
|
+
//#region src/validation/combinators.ts
|
|
4
|
+
function allOfValidator(report, schema, json) {
|
|
5
|
+
for (let i = 0; i < schema.allOf.length; i++) {
|
|
6
|
+
const validateResult = this._jsonValidate(report, schema.allOf[i], json);
|
|
7
|
+
if (this.options.breakOnFirstError && validateResult === false) break;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function anyOfValidator(report, schema, json) {
|
|
11
|
+
const subReports = [];
|
|
12
|
+
for (let i = 0; i < schema.anyOf.length; i++) {
|
|
13
|
+
const subReport = new Report(report);
|
|
14
|
+
subReports.push(subReport);
|
|
15
|
+
this._jsonValidate(subReport, schema.anyOf[i], json);
|
|
16
|
+
cacheValidationResult(report, schema.anyOf[i], json, subReport.errors.length === 0);
|
|
17
|
+
}
|
|
18
|
+
deferOrRunSync(report, subReports, () => {
|
|
19
|
+
let passed = false;
|
|
20
|
+
for (const subReport of subReports) if (subReport.errors.length === 0) {
|
|
21
|
+
passed = true;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
if (passed === false) report.addError("ANY_OF_MISSING", void 0, subReports, schema, "anyOf");
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function oneOfValidator(report, schema, json) {
|
|
28
|
+
const subReports = [];
|
|
29
|
+
for (let i = 0; i < schema.oneOf.length; i++) {
|
|
30
|
+
const subReport = new Report(report);
|
|
31
|
+
subReports.push(subReport);
|
|
32
|
+
this._jsonValidate(subReport, schema.oneOf[i], json);
|
|
33
|
+
cacheValidationResult(report, schema.oneOf[i], json, subReport.errors.length === 0);
|
|
34
|
+
}
|
|
35
|
+
deferOrRunSync(report, subReports, () => {
|
|
36
|
+
let passes = 0;
|
|
37
|
+
for (const subReport of subReports) if (subReport.errors.length === 0) passes++;
|
|
38
|
+
if (passes === 0) report.addError("ONE_OF_MISSING", void 0, subReports, schema, "oneOf");
|
|
39
|
+
else if (passes > 1) report.addError("ONE_OF_MULTIPLE", void 0, void 0, schema, "oneOf");
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function notValidator(report, schema, json) {
|
|
43
|
+
const subReport = new Report(report);
|
|
44
|
+
if (this._jsonValidate(subReport, schema.not, json) === true) report.addError("NOT_PASSED", void 0, void 0, schema, "not");
|
|
45
|
+
}
|
|
46
|
+
function ifValidator(report, schema, json) {
|
|
47
|
+
if (this.options.version === "draft-04" || this.options.version === "draft-06") return;
|
|
48
|
+
const conditionSchema = schema.if;
|
|
49
|
+
const thenSchema = schema.then;
|
|
50
|
+
const elseSchema = schema.else;
|
|
51
|
+
if (conditionSchema === void 0 || thenSchema === void 0 && elseSchema === void 0) return;
|
|
52
|
+
const conditionReport = new Report(report);
|
|
53
|
+
this._jsonValidate(conditionReport, conditionSchema, json);
|
|
54
|
+
cacheValidationResult(report, conditionSchema, json, conditionReport.errors.length === 0);
|
|
55
|
+
const branchSchema = conditionReport.errors.length === 0 ? thenSchema : elseSchema;
|
|
56
|
+
if (branchSchema === void 0) return;
|
|
57
|
+
this._jsonValidate(report, branchSchema, json);
|
|
58
|
+
}
|
|
59
|
+
function thenValidator() {}
|
|
60
|
+
function elseValidator() {}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { allOfValidator, anyOfValidator, elseValidator, ifValidator, notValidator, oneOfValidator, thenValidator };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { shouldSkipValidate } from "./shared.mjs";
|
|
2
|
+
//#region src/validation/numeric.ts
|
|
3
|
+
function multipleOfValidator(report, schema, json) {
|
|
4
|
+
if (shouldSkipValidate(this.validateOptions, ["MULTIPLE_OF"])) return;
|
|
5
|
+
if (typeof json !== "number") return;
|
|
6
|
+
const result = json / schema.multipleOf;
|
|
7
|
+
if (!Number.isFinite(result) || Math.abs(result - Math.round(result)) >= 1e-10) report.addError("MULTIPLE_OF", [json, schema.multipleOf], void 0, schema, "multipleOf");
|
|
8
|
+
}
|
|
9
|
+
function maximumValidator(report, schema, json) {
|
|
10
|
+
if (shouldSkipValidate(this.validateOptions, ["MAXIMUM", "MAXIMUM_EXCLUSIVE"])) return;
|
|
11
|
+
if (typeof json !== "number") return;
|
|
12
|
+
if (schema.exclusiveMaximum !== true) {
|
|
13
|
+
if (json > schema.maximum) report.addError("MAXIMUM", [json, schema.maximum], void 0, schema, "maximum");
|
|
14
|
+
} else if (json >= schema.maximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.maximum], void 0, schema, "maximum");
|
|
15
|
+
}
|
|
16
|
+
function exclusiveMaximumValidator(report, schema, json) {
|
|
17
|
+
if (typeof schema.exclusiveMaximum === "number") {
|
|
18
|
+
if (shouldSkipValidate(this.validateOptions, ["MAXIMUM_EXCLUSIVE"])) return;
|
|
19
|
+
if (typeof json !== "number") return;
|
|
20
|
+
if (json >= schema.exclusiveMaximum) report.addError("MAXIMUM_EXCLUSIVE", [json, schema.exclusiveMaximum], void 0, schema, "exclusiveMaximum");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function minimumValidator(report, schema, json) {
|
|
24
|
+
if (shouldSkipValidate(this.validateOptions, ["MINIMUM", "MINIMUM_EXCLUSIVE"])) return;
|
|
25
|
+
if (typeof json !== "number") return;
|
|
26
|
+
if (schema.exclusiveMinimum !== true) {
|
|
27
|
+
if (json < schema.minimum) report.addError("MINIMUM", [json, schema.minimum], void 0, schema, "minimum");
|
|
28
|
+
} else if (json <= schema.minimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.minimum], void 0, schema, "minimum");
|
|
29
|
+
}
|
|
30
|
+
function exclusiveMinimumValidator(report, schema, json) {
|
|
31
|
+
if (typeof schema.exclusiveMinimum === "number") {
|
|
32
|
+
if (shouldSkipValidate(this.validateOptions, ["MINIMUM_EXCLUSIVE"])) return;
|
|
33
|
+
if (typeof json !== "number") return;
|
|
34
|
+
if (json <= schema.exclusiveMinimum) report.addError("MINIMUM_EXCLUSIVE", [json, schema.exclusiveMinimum], void 0, schema, "exclusiveMinimum");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { exclusiveMaximumValidator, exclusiveMinimumValidator, maximumValidator, minimumValidator, multipleOfValidator };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { isObject } from "../utils/what-is.mjs";
|
|
2
|
+
import { compileSchemaRegex } from "../utils/schema-regex.mjs";
|
|
3
|
+
import { difference } from "../utils/array.mjs";
|
|
4
|
+
import { deferOrRunSync, shouldSkipValidate, supportsDependentKeywords } from "./shared.mjs";
|
|
5
|
+
//#region src/validation/object.ts
|
|
6
|
+
function maxPropertiesValidator(report, schema, json) {
|
|
7
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_PROPERTIES_MAXIMUM"])) return;
|
|
8
|
+
if (!isObject(json)) return;
|
|
9
|
+
const keysCount = Object.keys(json).length;
|
|
10
|
+
if (keysCount > schema.maxProperties) report.addError("OBJECT_PROPERTIES_MAXIMUM", [keysCount, schema.maxProperties], void 0, schema, "maxProperties");
|
|
11
|
+
}
|
|
12
|
+
function minPropertiesValidator(report, schema, json) {
|
|
13
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_PROPERTIES_MINIMUM"])) return;
|
|
14
|
+
if (!isObject(json)) return;
|
|
15
|
+
const keysCount = Object.keys(json).length;
|
|
16
|
+
if (keysCount < schema.minProperties) report.addError("OBJECT_PROPERTIES_MINIMUM", [keysCount, schema.minProperties], void 0, schema, "minProperties");
|
|
17
|
+
}
|
|
18
|
+
function requiredValidator(report, schema, json) {
|
|
19
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_MISSING_REQUIRED_PROPERTY"])) return;
|
|
20
|
+
if (!isObject(json)) return;
|
|
21
|
+
const idx = schema.required.length;
|
|
22
|
+
for (let i = 0; i < idx; i++) {
|
|
23
|
+
const requiredPropertyName = schema.required[i];
|
|
24
|
+
if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_MISSING_REQUIRED_PROPERTY", [requiredPropertyName], void 0, schema, "required");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function additionalPropertiesValidator(report, schema, json) {
|
|
28
|
+
if (schema.properties === void 0 && schema.patternProperties === void 0) return propertiesValidator.call(this, report, schema, json);
|
|
29
|
+
}
|
|
30
|
+
function patternPropertiesValidator(report, schema, json) {
|
|
31
|
+
if (schema.properties === void 0) return propertiesValidator.call(this, report, schema, json);
|
|
32
|
+
}
|
|
33
|
+
function propertiesValidator(report, schema, json) {
|
|
34
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_ADDITIONAL_PROPERTIES"])) return;
|
|
35
|
+
if (!isObject(json)) return;
|
|
36
|
+
const properties = schema.properties !== void 0 ? schema.properties : {};
|
|
37
|
+
const patternProperties = schema.patternProperties !== void 0 ? schema.patternProperties : {};
|
|
38
|
+
if (schema.additionalProperties === false) {
|
|
39
|
+
let s = Object.keys(json);
|
|
40
|
+
const p = Object.keys(properties);
|
|
41
|
+
const pp = Object.keys(patternProperties);
|
|
42
|
+
s = difference(s, p);
|
|
43
|
+
for (const ppKey of pp) {
|
|
44
|
+
const result = compileSchemaRegex(ppKey);
|
|
45
|
+
if (!result.ok) continue;
|
|
46
|
+
const regExp = result.value;
|
|
47
|
+
for (let idx2 = s.length - 1; idx2 >= 0; idx2--) if (regExp.test(s[idx2]) === true) s.splice(idx2, 1);
|
|
48
|
+
}
|
|
49
|
+
if (s.length > 0) {
|
|
50
|
+
if (Array.isArray(this.options.assumeAdditional)) for (const allowed of this.options.assumeAdditional) {
|
|
51
|
+
const io = s.indexOf(allowed);
|
|
52
|
+
if (io !== -1) s.splice(io, 1);
|
|
53
|
+
}
|
|
54
|
+
if (s.length > 0) for (const extra of s) report.addError("OBJECT_ADDITIONAL_PROPERTIES", [extra], void 0, schema, "properties");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function dependenciesValidator(report, schema, json) {
|
|
59
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
60
|
+
if (!isObject(json)) return;
|
|
61
|
+
const keys = Object.keys(schema.dependencies);
|
|
62
|
+
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
63
|
+
const dependencyDefinition = schema.dependencies[dependencyName];
|
|
64
|
+
if (Array.isArray(dependencyDefinition)) {
|
|
65
|
+
for (const requiredPropertyName of dependencyDefinition) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependencies");
|
|
66
|
+
} else this._jsonValidate(report, dependencyDefinition, json);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function dependentSchemasValidator(report, schema, json) {
|
|
70
|
+
if (!supportsDependentKeywords(schema, this.options.version)) return;
|
|
71
|
+
if (!isObject(json) || !isObject(schema.dependentSchemas)) return;
|
|
72
|
+
const keys = Object.keys(schema.dependentSchemas);
|
|
73
|
+
for (const dependencyName of keys) if (Object.hasOwn(json, dependencyName)) {
|
|
74
|
+
const dependencySchema = schema.dependentSchemas[dependencyName];
|
|
75
|
+
this._jsonValidate(report, dependencySchema, json);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function dependentRequiredValidator(report, schema, json) {
|
|
79
|
+
if (!supportsDependentKeywords(schema, this.options.version)) return;
|
|
80
|
+
if (shouldSkipValidate(this.validateOptions, ["OBJECT_DEPENDENCY_KEY"])) return;
|
|
81
|
+
if (!isObject(json) || !isObject(schema.dependentRequired)) return;
|
|
82
|
+
const keys = Object.keys(schema.dependentRequired);
|
|
83
|
+
for (const dependencyName of keys) {
|
|
84
|
+
if (!Object.hasOwn(json, dependencyName)) continue;
|
|
85
|
+
const requiredProperties = schema.dependentRequired[dependencyName];
|
|
86
|
+
if (!Array.isArray(requiredProperties)) continue;
|
|
87
|
+
for (const requiredPropertyName of requiredProperties) if (!Object.hasOwn(json, requiredPropertyName)) report.addError("OBJECT_DEPENDENCY_KEY", [requiredPropertyName, dependencyName], void 0, schema, "dependentRequired");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function propertyNamesValidator(report, schema, json) {
|
|
91
|
+
if (shouldSkipValidate(this.validateOptions, ["PROPERTY_NAMES"])) return;
|
|
92
|
+
if (!isObject(json)) return;
|
|
93
|
+
const propertyNamesSchema = schema.propertyNames;
|
|
94
|
+
if (propertyNamesSchema === void 0) return;
|
|
95
|
+
const Report_ = report.constructor;
|
|
96
|
+
const keys = Object.keys(json);
|
|
97
|
+
const subReports = [];
|
|
98
|
+
for (const key of keys) {
|
|
99
|
+
const subReport = new Report_(report);
|
|
100
|
+
subReports.push(subReport);
|
|
101
|
+
this._jsonValidate(subReport, propertyNamesSchema, key);
|
|
102
|
+
}
|
|
103
|
+
const addPropertyNameErrors = () => {
|
|
104
|
+
for (let idx = 0; idx < keys.length; idx++) if (subReports[idx].errors.length > 0) report.addError("PROPERTY_NAMES", [keys[idx]], subReports[idx], schema, void 0);
|
|
105
|
+
};
|
|
106
|
+
deferOrRunSync(report, subReports, addPropertyNameErrors);
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { additionalPropertiesValidator, dependenciesValidator, dependentRequiredValidator, dependentSchemasValidator, maxPropertiesValidator, minPropertiesValidator, patternPropertiesValidator, propertiesValidator, propertyNamesValidator, requiredValidator };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getRemotePath } from "../utils/uri.mjs";
|
|
2
|
+
import { findId, getId } from "../json-schema.mjs";
|
|
3
|
+
//#region src/validation/ref.ts
|
|
4
|
+
const getDynamicRefAnchorName = (dynamicRef) => {
|
|
5
|
+
const hashIdx = dynamicRef.indexOf("#");
|
|
6
|
+
if (hashIdx === -1) return;
|
|
7
|
+
const fragment = dynamicRef.slice(hashIdx + 1);
|
|
8
|
+
if (!fragment || fragment[0] === "/") return;
|
|
9
|
+
return fragment;
|
|
10
|
+
};
|
|
11
|
+
const findDynamicAnchorInScope = (scopeSchema, anchorName) => {
|
|
12
|
+
const scopeId = getId(scopeSchema);
|
|
13
|
+
const scopeBaseUri = scopeId ? getRemotePath(scopeId) : void 0;
|
|
14
|
+
const found = findId(scopeSchema, anchorName, scopeBaseUri, scopeBaseUri);
|
|
15
|
+
if (found && found.$dynamicAnchor === anchorName) return found;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the effective target for a $recursiveRef, walking the recursive anchor stack.
|
|
19
|
+
*/
|
|
20
|
+
const resolveRecursiveRef = (schema, recursiveAnchorStack) => {
|
|
21
|
+
const resolved = schema.__$recursiveRefResolved;
|
|
22
|
+
if (!resolved) return;
|
|
23
|
+
let target = resolved;
|
|
24
|
+
if (typeof target === "object" && target.$recursiveAnchor === true) {
|
|
25
|
+
const dynamicTarget = recursiveAnchorStack[0];
|
|
26
|
+
if (dynamicTarget) target = dynamicTarget;
|
|
27
|
+
}
|
|
28
|
+
return target;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Resolves the effective target for a $dynamicRef, walking the dynamic scope stack.
|
|
32
|
+
*/
|
|
33
|
+
const resolveDynamicRef = (schema, dynamicScopeStack) => {
|
|
34
|
+
const resolved = schema.__$dynamicRefResolved;
|
|
35
|
+
if (typeof resolved === "undefined" || !schema.$dynamicRef) return resolved;
|
|
36
|
+
let target = resolved;
|
|
37
|
+
const anchorName = getDynamicRefAnchorName(schema.$dynamicRef);
|
|
38
|
+
if (anchorName && typeof target === "object" && target.$dynamicAnchor === anchorName) for (let scopeIdx = 0; scopeIdx < dynamicScopeStack.length; scopeIdx++) {
|
|
39
|
+
const scopeSchema = dynamicScopeStack[scopeIdx];
|
|
40
|
+
const scopedTarget = findDynamicAnchorInScope(scopeSchema, anchorName);
|
|
41
|
+
if (scopedTarget) {
|
|
42
|
+
target = scopedTarget;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return target;
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { resolveDynamicRef, resolveRecursiveRef };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { isObject } from "../utils/what-is.mjs";
|
|
2
|
+
//#region src/validation/shared.ts
|
|
3
|
+
const shouldSkipValidate = function(options, errors) {
|
|
4
|
+
return options && Array.isArray(options.includeErrors) && options.includeErrors.length > 0 && !errors.some(function(err) {
|
|
5
|
+
return options.includeErrors.includes(err);
|
|
6
|
+
});
|
|
7
|
+
};
|
|
8
|
+
const supportsDependentKeywords = (schema, version) => {
|
|
9
|
+
if (typeof schema.$schema === "string") return !/draft-04|draft-06|draft-07/.test(schema.$schema);
|
|
10
|
+
return !(version === "draft-04" || version === "draft-06" || version === "draft-07");
|
|
11
|
+
};
|
|
12
|
+
const VOCAB_VALIDATION_2019_09 = "https://json-schema.org/draft/2019-09/vocab/validation";
|
|
13
|
+
const VOCAB_VALIDATION_2020_12 = "https://json-schema.org/draft/2020-12/vocab/validation";
|
|
14
|
+
const VOCAB_FORMAT_2019_09 = "https://json-schema.org/draft/2019-09/vocab/format";
|
|
15
|
+
const VOCAB_FORMAT_ASSERTION_2020_12 = "https://json-schema.org/draft/2020-12/vocab/format-assertion";
|
|
16
|
+
const VALIDATION_VOCAB_KEYWORDS = new Set([
|
|
17
|
+
"type",
|
|
18
|
+
"multipleOf",
|
|
19
|
+
"maximum",
|
|
20
|
+
"exclusiveMaximum",
|
|
21
|
+
"minimum",
|
|
22
|
+
"exclusiveMinimum",
|
|
23
|
+
"maxLength",
|
|
24
|
+
"minLength",
|
|
25
|
+
"pattern",
|
|
26
|
+
"maxItems",
|
|
27
|
+
"minItems",
|
|
28
|
+
"uniqueItems",
|
|
29
|
+
"maxContains",
|
|
30
|
+
"minContains",
|
|
31
|
+
"maxProperties",
|
|
32
|
+
"minProperties",
|
|
33
|
+
"required",
|
|
34
|
+
"dependentRequired",
|
|
35
|
+
"enum",
|
|
36
|
+
"const",
|
|
37
|
+
"contentEncoding",
|
|
38
|
+
"contentMediaType"
|
|
39
|
+
]);
|
|
40
|
+
const isValidationVocabularyEnabled = (schema, report, version) => {
|
|
41
|
+
if (version !== "draft2019-09" && version !== "draft2020-12") return true;
|
|
42
|
+
const currentSchemaMeta = schema.__$schemaResolved;
|
|
43
|
+
const rootSchemaMeta = report.rootSchema && typeof report.rootSchema !== "boolean" ? report.rootSchema.__$schemaResolved : void 0;
|
|
44
|
+
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
45
|
+
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return true;
|
|
46
|
+
const vocabulary = metaSchema.$vocabulary;
|
|
47
|
+
if (Object.hasOwn(vocabulary, VOCAB_VALIDATION_2019_09) || Object.hasOwn(vocabulary, VOCAB_VALIDATION_2020_12)) return vocabulary[VOCAB_VALIDATION_2019_09] === true || vocabulary[VOCAB_VALIDATION_2020_12] === true;
|
|
48
|
+
return false;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Checks whether the format-assertion vocabulary is enabled in the meta-schema.
|
|
52
|
+
* For draft 2019-09: checks if the format vocabulary is set to true.
|
|
53
|
+
* For draft 2020-12: checks if the format-assertion vocabulary is present and true.
|
|
54
|
+
* Returns true for older drafts (format was always an assertion).
|
|
55
|
+
*/
|
|
56
|
+
const isFormatAssertionVocabEnabled = (schema, report, version) => {
|
|
57
|
+
if (version !== "draft2019-09" && version !== "draft2020-12") return true;
|
|
58
|
+
const currentSchemaMeta = schema.__$schemaResolved;
|
|
59
|
+
const rootSchemaMeta = report.rootSchema && typeof report.rootSchema !== "boolean" ? report.rootSchema.__$schemaResolved : void 0;
|
|
60
|
+
const metaSchema = currentSchemaMeta || rootSchemaMeta;
|
|
61
|
+
if (!metaSchema || typeof metaSchema !== "object" || !isObject(metaSchema.$vocabulary)) return false;
|
|
62
|
+
const vocabulary = metaSchema.$vocabulary;
|
|
63
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_ASSERTION_2020_12)) return vocabulary[VOCAB_FORMAT_ASSERTION_2020_12] === true;
|
|
64
|
+
if (Object.hasOwn(vocabulary, VOCAB_FORMAT_2019_09)) return vocabulary[VOCAB_FORMAT_2019_09] === true;
|
|
65
|
+
return false;
|
|
66
|
+
};
|
|
67
|
+
function cacheValidationResult(report, schema, json, passed) {
|
|
68
|
+
let schemaMap = report.__validationResultCache.get(schema);
|
|
69
|
+
if (!schemaMap) {
|
|
70
|
+
schemaMap = /* @__PURE__ */ new Map();
|
|
71
|
+
report.__validationResultCache.set(schema, schemaMap);
|
|
72
|
+
}
|
|
73
|
+
schemaMap.set(json, passed);
|
|
74
|
+
}
|
|
75
|
+
function getCachedValidationResult(report, schema, json) {
|
|
76
|
+
return report.__validationResultCache.get(schema)?.get(json);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Shared async-task aggregation pattern.
|
|
80
|
+
*
|
|
81
|
+
* 1. Collects async tasks from `subReports` into `report`.
|
|
82
|
+
* 2. If new async tasks were added, defers `decisionFn` via `report.addAsyncTask`
|
|
83
|
+
* with proper path save/restore so error paths are correct.
|
|
84
|
+
* 3. Otherwise, runs `decisionFn` synchronously.
|
|
85
|
+
*/
|
|
86
|
+
function deferOrRunSync(report, subReports, decisionFn) {
|
|
87
|
+
const asyncTasksBefore = report.asyncTasks.length;
|
|
88
|
+
for (const subReport of subReports) report.asyncTasks.push(...subReport.asyncTasks);
|
|
89
|
+
if (report.asyncTasks.length > asyncTasksBefore) report.addAsyncTaskWithPath((callback) => {
|
|
90
|
+
setTimeout(() => callback(null), 0);
|
|
91
|
+
}, [], () => {
|
|
92
|
+
decisionFn();
|
|
93
|
+
});
|
|
94
|
+
else decisionFn();
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { VALIDATION_VOCAB_KEYWORDS, cacheValidationResult, deferOrRunSync, getCachedValidationResult, isFormatAssertionVocabEnabled, isValidationVocabularyEnabled, shouldSkipValidate, supportsDependentKeywords };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { whatIs } from "../utils/what-is.mjs";
|
|
2
|
+
import { getFormatValidators } from "../format-validators.mjs";
|
|
3
|
+
import { compileSchemaRegex } from "../utils/schema-regex.mjs";
|
|
4
|
+
import { isFormatAssertionVocabEnabled, shouldSkipValidate } from "./shared.mjs";
|
|
5
|
+
import { decodeBase64, isValidBase64 } from "../utils/base64.mjs";
|
|
6
|
+
import { unicodeLength } from "../utils/unicode.mjs";
|
|
7
|
+
//#region src/validation/string.ts
|
|
8
|
+
function minLengthValidator(report, schema, json) {
|
|
9
|
+
if (shouldSkipValidate(this.validateOptions, ["MIN_LENGTH"])) return;
|
|
10
|
+
if (typeof json !== "string") return;
|
|
11
|
+
if (unicodeLength(json) < schema.minLength) report.addError("MIN_LENGTH", [json.length, schema.minLength], void 0, schema, "minLength");
|
|
12
|
+
}
|
|
13
|
+
function maxLengthValidator(report, schema, json) {
|
|
14
|
+
if (shouldSkipValidate(this.validateOptions, ["MAX_LENGTH"])) return;
|
|
15
|
+
if (typeof json !== "string") return;
|
|
16
|
+
if (unicodeLength(json) > schema.maxLength) report.addError("MAX_LENGTH", [json.length, schema.maxLength], void 0, schema, "maxLength");
|
|
17
|
+
}
|
|
18
|
+
function patternValidator(report, schema, json) {
|
|
19
|
+
if (shouldSkipValidate(this.validateOptions, ["PATTERN"])) return;
|
|
20
|
+
if (typeof json !== "string") return;
|
|
21
|
+
const result = compileSchemaRegex(schema.pattern);
|
|
22
|
+
if (!result.ok) {
|
|
23
|
+
report.addError("PATTERN", [
|
|
24
|
+
schema.pattern,
|
|
25
|
+
json,
|
|
26
|
+
result.error.message
|
|
27
|
+
], void 0, schema, "pattern");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!result.value.test(json)) report.addError("PATTERN", [schema.pattern, json], void 0, schema, "pattern");
|
|
31
|
+
}
|
|
32
|
+
function formatValidator(report, schema, json) {
|
|
33
|
+
if (this.options.formatAssertions === false) return;
|
|
34
|
+
if (this.options.formatAssertions === true) {
|
|
35
|
+
if (!isFormatAssertionVocabEnabled(schema, report, this.options.version)) return;
|
|
36
|
+
}
|
|
37
|
+
const isModernDraft = this.options.version === "draft2019-09" || this.options.version === "draft2020-12";
|
|
38
|
+
const formatValidatorFn = getFormatValidators(this.options)[schema.format];
|
|
39
|
+
if (typeof formatValidatorFn === "function") {
|
|
40
|
+
if (shouldSkipValidate(this.validateOptions, ["INVALID_FORMAT"])) return;
|
|
41
|
+
if (report.hasError("INVALID_TYPE", [schema.type, whatIs(json)])) return;
|
|
42
|
+
if (formatValidatorFn.length === 2) report.addAsyncTaskWithPath(formatValidatorFn, [json], function(result) {
|
|
43
|
+
if (result !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
44
|
+
});
|
|
45
|
+
else {
|
|
46
|
+
const result = formatValidatorFn.call(this, json);
|
|
47
|
+
if (result instanceof Promise) {
|
|
48
|
+
const promiseResult = result;
|
|
49
|
+
report.addAsyncTaskWithPath(async (callback) => {
|
|
50
|
+
try {
|
|
51
|
+
callback(await promiseResult);
|
|
52
|
+
} catch (_error) {
|
|
53
|
+
callback(false);
|
|
54
|
+
}
|
|
55
|
+
}, [], function(resolvedResult) {
|
|
56
|
+
if (resolvedResult !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
57
|
+
});
|
|
58
|
+
} else if (result !== true) report.addError("INVALID_FORMAT", [schema.format, JSON.stringify(json)], void 0, schema, "format");
|
|
59
|
+
}
|
|
60
|
+
} else if (this.options.ignoreUnknownFormats !== true && !isModernDraft) report.addError("UNKNOWN_FORMAT", [schema.format], void 0, schema, "format");
|
|
61
|
+
}
|
|
62
|
+
function contentEncodingValidator(report, schema, json) {
|
|
63
|
+
if (this.options.version !== "draft-07") return;
|
|
64
|
+
if (typeof json !== "string") return;
|
|
65
|
+
if (schema.contentEncoding !== "base64") return;
|
|
66
|
+
if (!isValidBase64(json)) report.addError("INVALID_FORMAT", ["contentEncoding:base64", JSON.stringify(json)], void 0, schema, "contentEncoding");
|
|
67
|
+
}
|
|
68
|
+
function contentMediaTypeValidator(report, schema, json) {
|
|
69
|
+
if (this.options.version !== "draft-07") return;
|
|
70
|
+
if (typeof json !== "string") return;
|
|
71
|
+
if (schema.contentMediaType !== "application/json") return;
|
|
72
|
+
let payload = json;
|
|
73
|
+
if (schema.contentEncoding === "base64") {
|
|
74
|
+
const decoded = decodeBase64(json);
|
|
75
|
+
if (decoded === void 0) {
|
|
76
|
+
report.addError("INVALID_FORMAT", ["contentEncoding:base64", JSON.stringify(json)], void 0, schema, "contentEncoding");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
payload = decoded;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
JSON.parse(payload);
|
|
83
|
+
} catch {
|
|
84
|
+
report.addError("INVALID_FORMAT", ["contentMediaType:application/json", JSON.stringify(json)], void 0, schema, "contentMediaType");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { contentEncodingValidator, contentMediaTypeValidator, formatValidator, maxLengthValidator, minLengthValidator, patternValidator };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { whatIs } from "../utils/what-is.mjs";
|
|
2
|
+
import { areEqual } from "../utils/json.mjs";
|
|
3
|
+
import { shouldSkipValidate } from "./shared.mjs";
|
|
4
|
+
//#region src/validation/type.ts
|
|
5
|
+
function typeValidator(report, schema, json) {
|
|
6
|
+
if (shouldSkipValidate(this.validateOptions, ["INVALID_TYPE"])) return;
|
|
7
|
+
const jsonType = whatIs(json);
|
|
8
|
+
if (typeof schema.type === "string") {
|
|
9
|
+
if (jsonType !== schema.type && (jsonType !== "integer" || schema.type !== "number")) report.addError("INVALID_TYPE", [schema.type, jsonType], void 0, schema, "type");
|
|
10
|
+
} else if (!schema.type.includes(jsonType) && (jsonType !== "integer" || !schema.type.includes("number"))) report.addError("INVALID_TYPE", [JSON.stringify(schema.type), jsonType], void 0, schema, "type");
|
|
11
|
+
}
|
|
12
|
+
function enumValidator(report, schema, json) {
|
|
13
|
+
if (shouldSkipValidate(this.validateOptions, ["ENUM_CASE_MISMATCH", "ENUM_MISMATCH"])) return;
|
|
14
|
+
let match = false, caseInsensitiveMatch = false;
|
|
15
|
+
for (const enumVal of schema.enum) if (areEqual(json, enumVal, { maxDepth: this.options.maxRecursionDepth })) {
|
|
16
|
+
match = true;
|
|
17
|
+
break;
|
|
18
|
+
} else if (areEqual(json, enumVal, {
|
|
19
|
+
caseInsensitiveComparison: true,
|
|
20
|
+
maxDepth: this.options.maxRecursionDepth
|
|
21
|
+
})) caseInsensitiveMatch = true;
|
|
22
|
+
if (match === false) {
|
|
23
|
+
const error = caseInsensitiveMatch && this.options.enumCaseInsensitiveComparison ? "ENUM_CASE_MISMATCH" : "ENUM_MISMATCH";
|
|
24
|
+
report.addError(error, [JSON.stringify(json)], void 0, schema, "enum");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function constValidator(report, schema, json) {
|
|
28
|
+
const constValue = schema.const;
|
|
29
|
+
if (areEqual(json, constValue, { maxDepth: this.options.maxRecursionDepth }) === false) report.addError("CONST", [JSON.stringify(constValue)], void 0, schema, void 0);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { constValidator, enumValidator, typeValidator };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { FormatValidatorFn } from "./format-validators.mjs";
|
|
2
|
+
import { ZSchemaOptions } from "./z-schema-options.mjs";
|
|
3
|
+
import { Report } from "./report.mjs";
|
|
4
|
+
import { Errors, ValidateError } from "./errors.mjs";
|
|
5
|
+
import { SchemaCache } from "./schema-cache.mjs";
|
|
6
|
+
import { SchemaValidator } from "./schema-validator.mjs";
|
|
7
|
+
import { SchemaCompiler } from "./schema-compiler.mjs";
|
|
8
|
+
import { JsonSchema, JsonSchemaInternal } from "./json-schema-versions.mjs";
|
|
9
|
+
|
|
10
|
+
//#region src/z-schema-base.d.ts
|
|
11
|
+
interface ValidateOptions {
|
|
12
|
+
schemaPath?: string;
|
|
13
|
+
includeErrors?: Array<keyof typeof Errors>;
|
|
14
|
+
excludeErrors?: Array<keyof typeof Errors>;
|
|
15
|
+
}
|
|
16
|
+
type ValidateResponse = {
|
|
17
|
+
valid: boolean;
|
|
18
|
+
err?: ValidateError;
|
|
19
|
+
};
|
|
20
|
+
type ValidateCallback = (err: ValidateResponse['err'], valid: ValidateResponse['valid']) => void;
|
|
21
|
+
declare class ZSchemaBase {
|
|
22
|
+
scache: SchemaCache;
|
|
23
|
+
sc: SchemaCompiler;
|
|
24
|
+
sv: SchemaValidator;
|
|
25
|
+
validateOptions: ValidateOptions;
|
|
26
|
+
options: ZSchemaOptions;
|
|
27
|
+
constructor(options: ZSchemaOptions | undefined, token: symbol);
|
|
28
|
+
/**
|
|
29
|
+
* Internal recursive JSON validation — delegates to the `validate` function
|
|
30
|
+
* in `json-validation.ts`. Exposed as a method so that per-keyword validator
|
|
31
|
+
* modules (array, combinators, object) can call back into the core validator
|
|
32
|
+
* via `this` without importing `json-validation.ts` directly (which would
|
|
33
|
+
* create a circular dependency).
|
|
34
|
+
*/
|
|
35
|
+
_jsonValidate(report: Report, schema: boolean | JsonSchemaInternal, json: unknown): boolean;
|
|
36
|
+
getDefaultSchemaId(): string;
|
|
37
|
+
_validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions, callback: ValidateCallback): void;
|
|
38
|
+
_validate(json: unknown, schema: JsonSchema | string, callback: ValidateCallback): void;
|
|
39
|
+
_validate(json: unknown, schema: JsonSchema | string, options: ValidateOptions): true;
|
|
40
|
+
_validate(json: unknown, schema: JsonSchema | string): true;
|
|
41
|
+
_validateSchema(schemaOrArr: JsonSchema | JsonSchema[]): true;
|
|
42
|
+
/**
|
|
43
|
+
* Register a format validator on this instance only (does not affect other instances or the global registry).
|
|
44
|
+
* @param name - The format name.
|
|
45
|
+
* @param validatorFunction - A sync or async function `(value: unknown) => boolean | Promise<boolean>`.
|
|
46
|
+
*/
|
|
47
|
+
registerFormat(name: string, validatorFunction: FormatValidatorFn): void;
|
|
48
|
+
/**
|
|
49
|
+
* Unregister an instance-scoped format validator.
|
|
50
|
+
* @param name - The format name to unregister.
|
|
51
|
+
*/
|
|
52
|
+
unregisterFormat(name: string): void;
|
|
53
|
+
/** Returns the names of format validators registered on this instance. */
|
|
54
|
+
getRegisteredFormats(): string[];
|
|
55
|
+
/** Returns all supported format names (global + instance-registered). */
|
|
56
|
+
getSupportedFormats(): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Register a remote schema in this instance's cache so `$ref` can resolve to it.
|
|
59
|
+
* @param uri - The URI the schema will be known by.
|
|
60
|
+
* @param schema - The schema object or JSON string.
|
|
61
|
+
* @param validationOptions - Optional options used for schema preparation.
|
|
62
|
+
*/
|
|
63
|
+
setRemoteReference(uri: string, schema: string | JsonSchema, validationOptions?: ZSchemaOptions): void;
|
|
64
|
+
/**
|
|
65
|
+
* Extract unresolvable `$ref` URIs from a validation error.
|
|
66
|
+
* @param err - A `ValidateError` from a failed validation.
|
|
67
|
+
* @returns An array of unresolvable reference URIs.
|
|
68
|
+
*/
|
|
69
|
+
getMissingReferences(err: ValidateError): string[];
|
|
70
|
+
/**
|
|
71
|
+
* Extract unresolvable **remote** `$ref` URIs from a validation error (local fragment-only refs are excluded).
|
|
72
|
+
* @param err - A `ValidateError` from a failed validation.
|
|
73
|
+
* @returns An array of remote reference base URIs.
|
|
74
|
+
*/
|
|
75
|
+
getMissingRemoteReferences(err: ValidateError): string[];
|
|
76
|
+
/**
|
|
77
|
+
* Resolve a previously compiled schema by its `$id` / `id`, cleaning up internal bookkeeping properties
|
|
78
|
+
* and inlining resolved `$ref` targets.
|
|
79
|
+
* @param schemaId - The schema identifier to look up.
|
|
80
|
+
* @returns A clean, resolved copy of the schema, or `undefined` if not found.
|
|
81
|
+
*/
|
|
82
|
+
getResolvedSchema(schemaId: string): JsonSchema | undefined;
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { ValidateCallback, ValidateOptions, ValidateResponse, ZSchemaBase };
|