z-schema 6.0.2 → 7.0.0-beta.2

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 (51) hide show
  1. package/README.md +154 -134
  2. package/bin/z-schema +128 -124
  3. package/cjs/ZSchema.d.ts +227 -0
  4. package/cjs/ZSchema.js +13785 -0
  5. package/dist/Errors.js +50 -0
  6. package/dist/FormatValidators.js +136 -0
  7. package/{src → dist}/JsonValidation.js +184 -213
  8. package/dist/Report.js +220 -0
  9. package/{src → dist}/SchemaCache.js +67 -82
  10. package/{src → dist}/SchemaCompilation.js +89 -129
  11. package/dist/SchemaValidation.js +631 -0
  12. package/{src → dist}/Utils.js +96 -104
  13. package/dist/ZSchema.js +365 -0
  14. package/dist/index.js +2 -0
  15. package/dist/schemas/hyper-schema.json +156 -0
  16. package/dist/schemas/schema.json +151 -0
  17. package/dist/types/Errors.d.ts +44 -0
  18. package/dist/types/FormatValidators.d.ts +12 -0
  19. package/dist/types/JsonValidation.d.ts +37 -0
  20. package/dist/types/Report.d.ts +87 -0
  21. package/dist/types/SchemaCache.d.ts +26 -0
  22. package/dist/types/SchemaCompilation.d.ts +1 -0
  23. package/dist/types/SchemaValidation.d.ts +6 -0
  24. package/dist/types/Utils.d.ts +64 -0
  25. package/dist/types/ZSchema.d.ts +97 -0
  26. package/dist/types/index.d.ts +2 -0
  27. package/package.json +59 -45
  28. package/src/Errors.ts +56 -0
  29. package/src/FormatValidators.ts +136 -0
  30. package/src/JsonValidation.ts +624 -0
  31. package/src/Report.ts +337 -0
  32. package/src/SchemaCache.ts +189 -0
  33. package/src/SchemaCompilation.ts +293 -0
  34. package/src/SchemaValidation.ts +629 -0
  35. package/src/Utils.ts +286 -0
  36. package/src/ZSchema.ts +467 -0
  37. package/src/index.ts +3 -0
  38. package/src/schemas/_ +0 -0
  39. package/umd/ZSchema.js +13791 -0
  40. package/umd/ZSchema.min.js +1 -0
  41. package/dist/ZSchema-browser-min.js +0 -2
  42. package/dist/ZSchema-browser-min.js.map +0 -1
  43. package/dist/ZSchema-browser-test.js +0 -32247
  44. package/dist/ZSchema-browser.js +0 -12745
  45. package/index.d.ts +0 -175
  46. package/src/Errors.js +0 -60
  47. package/src/FormatValidators.js +0 -129
  48. package/src/Polyfills.js +0 -16
  49. package/src/Report.js +0 -299
  50. package/src/SchemaValidation.js +0 -619
  51. package/src/ZSchema.js +0 -409
package/bin/z-schema CHANGED
@@ -3,45 +3,52 @@
3
3
  // set default exitCode for node 0.10
4
4
  process.exitCode = 0;
5
5
 
6
- var fs = require("fs");
7
- var path = require("path");
8
- var program = require("commander");
9
- var request = require("https").request;
10
- var package = require("./../package.json");
11
- var ZSchema = require("./../src/ZSchema");
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { program } from 'commander';
9
+ import { request } from 'https';
10
+ import pkg from '../package.json' with { type: 'json' };
11
+ import ZSchema from '../dist/index.js';
12
12
 
13
13
  program
14
- .version(package.version)
15
- .usage("[options] <schema> <json1?> <json2?> <json3?>")
16
- .option("--asyncTimeout <n>", "default timeout for all async tasks", parseInt)
17
- .option("--forceAdditional", "force additionalProperties and additionalItems to be defined on \"object\" and \"array\" types")
18
- .option("--assumeAdditional", "assume additionalProperties and additionalItems are defined as \"false\" where appropriate")
19
- .option("--forceItems", "force items to be defined on \"array\" types")
20
- .option("--forceMinItems", "force minItems to be defined on \"array\" types")
21
- .option("--forceMaxItems", "force maxItems to be defined on \"array\" types")
22
- .option("--forceMinLength", "force minLength to be defined on \"string\" types")
23
- .option("--forceMaxLength", "force maxLength to be defined on \"string\" types")
24
- .option("--forceProperties", "force properties or patternProperties to be defined on \"object\" types")
25
- .option("--ignoreUnresolvableReferences", "ignore references that cannot be resolved (remote schemas)")
26
- .option("--noExtraKeywords", "disallow usage of keywords that this validator can't handle")
27
- .option("--noTypeless", "disallow usage of schema's without \"type\" defined")
28
- .option("--noEmptyStrings", "disallow zero length strings in validated objects")
29
- .option("--noEmptyArrays", "disallow zero length arrays in validated objects")
30
- .option("--strictUris", "forces \"uri\" format to be in fully rfc3986 compliant")
31
- .option("--strictMode", "turn on some of the above")
32
- .option("--reportPathAsArray", "report error paths as an array of path segments to get to the offending node")
33
- .option("--breakOnFirstError", "stops validation as soon as an error is found, true by default but can be turned off")
34
- .option("--pedanticCheck", "check if schema follow best practices and common sence")
35
- .option("--ignoreUnknownFormats", "ignore unknown formats (do not report them as an error)")
14
+ .version(pkg.version)
15
+ .usage('[options] <schema> <json1?> <json2?> <json3?>')
16
+ .option('--asyncTimeout <n>', 'default timeout for all async tasks', parseInt)
17
+ .option(
18
+ '--forceAdditional',
19
+ 'force additionalProperties and additionalItems to be defined on "object" and "array" types'
20
+ )
21
+ .option(
22
+ '--assumeAdditional',
23
+ 'assume additionalProperties and additionalItems are defined as "false" where appropriate'
24
+ )
25
+ .option('--forceItems', 'force items to be defined on "array" types')
26
+ .option('--forceMinItems', 'force minItems to be defined on "array" types')
27
+ .option('--forceMaxItems', 'force maxItems to be defined on "array" types')
28
+ .option('--forceMinLength', 'force minLength to be defined on "string" types')
29
+ .option('--forceMaxLength', 'force maxLength to be defined on "string" types')
30
+ .option('--forceProperties', 'force properties or patternProperties to be defined on "object" types')
31
+ .option('--ignoreUnresolvableReferences', 'ignore references that cannot be resolved (remote schemas)')
32
+ .option('--noExtraKeywords', "disallow usage of keywords that this validator can't handle")
33
+ .option('--noTypeless', 'disallow usage of schema\'s without "type" defined')
34
+ .option('--noEmptyStrings', 'disallow zero length strings in validated objects')
35
+ .option('--noEmptyArrays', 'disallow zero length arrays in validated objects')
36
+ .option('--strictUris', 'forces "uri" format to be in fully rfc3986 compliant')
37
+ .option('--strictMode', 'turn on some of the above')
38
+ .option('--reportPathAsArray', 'report error paths as an array of path segments to get to the offending node')
39
+ .option('--breakOnFirstError', 'stops validation as soon as an error is found, true by default but can be turned off')
40
+ .option('--pedanticCheck', 'check if schema follow best practices and common sence')
41
+ .option('--ignoreUnknownFormats', 'ignore unknown formats (do not report them as an error)')
42
+ .allowExcessArguments()
36
43
  .parse(process.argv);
37
-
38
- var options = {};
44
+
45
+ var options = {};
39
46
  var defaultOptions = ZSchema.getDefaultOptions();
40
47
 
41
48
  for (var key in defaultOptions) {
42
- if (program[key]) {
43
- options[key] = program[key];
44
- }
49
+ if (program[key]) {
50
+ options[key] = program[key];
51
+ }
45
52
  }
46
53
 
47
54
  if (!program.args.length) {
@@ -49,20 +56,20 @@ if (!program.args.length) {
49
56
  }
50
57
 
51
58
  function readJson(fileName) {
52
- var ret;
53
- try {
54
- ret = fs.readFileSync(fileName, { encoding: "utf8" });
55
- } catch (e) {
56
- console.error(e);
57
- throw new Error("Couldn't read the file: " + fileName);
58
- }
59
- try {
60
- ret = JSON.parse(ret);
61
- } catch (e) {
62
- console.error(e);
63
- throw new Error("Couldn't parse the file as JSON: " + fileName);
64
- }
65
- return ret;
59
+ var ret;
60
+ try {
61
+ ret = fs.readFileSync(fileName, { encoding: 'utf8' });
62
+ } catch (e) {
63
+ console.error(e);
64
+ throw new Error("Couldn't read the file: " + fileName);
65
+ }
66
+ try {
67
+ ret = JSON.parse(ret);
68
+ } catch (e) {
69
+ console.error(e);
70
+ throw new Error("Couldn't parse the file as JSON: " + fileName);
71
+ }
72
+ return ret;
66
73
  }
67
74
 
68
75
  var validator = new ZSchema(options);
@@ -70,100 +77,97 @@ var schemaFilePath = program.args.shift();
70
77
  var schema = readJson(schemaFilePath);
71
78
 
72
79
  function validateWithAutomaticDownloads(filePath, data, schema, callback) {
80
+ var lastResult;
73
81
 
74
- var lastResult;
82
+ function finish() {
83
+ callback(validator.getLastErrors(), lastResult);
84
+ }
75
85
 
76
- function finish() {
77
- callback(validator.getLastErrors(), lastResult);
86
+ function validate() {
87
+ if (data !== undefined) {
88
+ lastResult = validator.validate(data, schema);
89
+ } else {
90
+ lastResult = validator.validateSchema(schema);
78
91
  }
79
92
 
80
- function validate() {
93
+ // console.log(lastResult);
94
+ // console.log(JSON.stringify(validator.getLastErrors(), null, 4));
81
95
 
82
- if (data !== undefined) {
83
- lastResult = validator.validate(data, schema);
84
- } else {
85
- lastResult = validator.validateSchema(schema);
86
- }
87
-
88
- // console.log(lastResult);
89
- // console.log(JSON.stringify(validator.getLastErrors(), null, 4));
90
-
91
- var missingReferences = validator.getMissingRemoteReferences();
92
- if (missingReferences.length > 0) {
93
- var finished = 0;
94
- missingReferences.forEach(function (url) {
95
- var urlString = "request: " + url + " - ";
96
-
97
- if (url.match(/^https?:/)) {
98
- request(url, function (response) {
99
- var body = "";
100
- response.on("data", function (chunk) { data += chunk; });
101
- response.on("end", function () {
102
-
103
- console.log(urlString + response.statusCode);
104
-
105
- validator.setRemoteReference(url, JSON.parse(body));
106
- finished++;
107
- if (finished === missingReferences.length) {
108
- validate();
109
- }
110
- });
111
- }).on("error", function (error) {
112
- console.error(urlString);
113
- console.error(error);
114
- process.exit(1);
115
- });
116
- } else {
117
- // FUTURE: maybe else if (isFile(url)) later
118
- var referencePath = path.resolve(process.cwd(), path.dirname(filePath), url);
119
- var reference = readJson(referencePath);
120
- validator.setRemoteReference(url, reference);
121
- finished++;
122
- if (finished === missingReferences.length) {
123
- validate();
124
- }
125
- }
96
+ var missingReferences = validator.getMissingRemoteReferences();
97
+ if (missingReferences.length > 0) {
98
+ var finished = 0;
99
+ missingReferences.forEach(function (url) {
100
+ var urlString = 'request: ' + url + ' - ';
101
+
102
+ if (url.match(/^https?:/)) {
103
+ request(url, function (response) {
104
+ var body = '';
105
+ response.on('data', function (chunk) {
106
+ data += chunk;
107
+ });
108
+ response.on('end', function () {
109
+ console.log(urlString + response.statusCode);
110
+
111
+ validator.setRemoteReference(url, JSON.parse(body));
112
+ finished++;
113
+ if (finished === missingReferences.length) {
114
+ validate();
115
+ }
126
116
  });
117
+ }).on('error', function (error) {
118
+ console.error(urlString);
119
+ console.error(error);
120
+ process.exit(1);
121
+ });
127
122
  } else {
128
- finish();
123
+ // FUTURE: maybe else if (isFile(url)) later
124
+ var referencePath = path.resolve(process.cwd(), path.dirname(filePath), url);
125
+ var reference = readJson(referencePath);
126
+ validator.setRemoteReference(url, reference);
127
+ finished++;
128
+ if (finished === missingReferences.length) {
129
+ validate();
130
+ }
129
131
  }
130
-
132
+ });
133
+ } else {
134
+ finish();
131
135
  }
136
+ }
132
137
 
133
- validate();
134
-
138
+ validate();
135
139
  }
136
140
 
137
141
  var i = 0;
138
142
  function validateJsons() {
139
- if (program.args.length === 0) {
140
- process.exit(process.exitCode);
141
- return;
143
+ if (program.args.length === 0) {
144
+ process.exit(process.exitCode);
145
+ return;
146
+ }
147
+ i++;
148
+
149
+ var filePath = program.args.shift();
150
+ var json = readJson(filePath);
151
+ validateWithAutomaticDownloads(filePath, json, schema, function (errs, isValid) {
152
+ if (!isValid) {
153
+ console.log(JSON.stringify(validator.getLastErrors(), null, 4));
154
+ console.log('json #' + i + ' validation failed');
155
+ process.exitCode = 1;
156
+ } else {
157
+ console.log('json #' + i + ' validation passed');
142
158
  }
143
- i++;
144
-
145
- var filePath = program.args.shift();
146
- var json = readJson(filePath);
147
- validateWithAutomaticDownloads(filePath, json, schema, function (errs, isValid) {
148
- if (!isValid) {
149
- console.log(JSON.stringify(validator.getLastErrors(), null, 4));
150
- console.log("json #" + i + " validation failed");
151
- process.exitCode = 1;
152
- } else {
153
- console.log("json #" + i + " validation passed");
154
- }
155
- validateJsons();
156
- });
159
+ validateJsons();
160
+ });
157
161
  }
158
162
 
159
163
  // validate schema
160
164
  validateWithAutomaticDownloads(schemaFilePath, undefined, schema, function (errs, isValid) {
161
- if (!isValid) {
162
- console.log(JSON.stringify(validator.getLastErrors(), null, 4));
163
- console.log("schema validation failed");
164
- process.exit(1);
165
- } else {
166
- console.log("schema validation passed");
167
- validateJsons();
168
- }
165
+ if (!isValid) {
166
+ console.log(JSON.stringify(validator.getLastErrors(), null, 4));
167
+ console.log('schema validation failed');
168
+ process.exit(1);
169
+ } else {
170
+ console.log('schema validation passed');
171
+ validateJsons();
172
+ }
169
173
  });
@@ -0,0 +1,227 @@
1
+ interface SchemaError extends Error {
2
+ /**
3
+ * Implements the Error.name contract. The value is always "z-schema validation error".
4
+ */
5
+ name: string;
6
+ /**
7
+ * An identifier indicating the type of error.
8
+ * Example: "JSON_OBJECT_VALIDATION_FAILED"
9
+ */
10
+ message: string;
11
+ /**
12
+ * Returns details for each error that occurred during validation.
13
+ * See Options.breakOnFirstError.
14
+ */
15
+ details?: SchemaErrorDetail[];
16
+ }
17
+ interface SchemaErrorDetail {
18
+ /**
19
+ * Example: "Expected type string but found type array"
20
+ */
21
+ message: string;
22
+ /**
23
+ * An error identifier that can be used to format a custom error message.
24
+ * Example: "INVALID_TYPE"
25
+ */
26
+ code: string;
27
+ /**
28
+ * Format parameters that can be used to format a custom error message.
29
+ * Example: ["string","array"]
30
+ */
31
+ params: Array<string>;
32
+ /**
33
+ * A JSON path indicating the location of the error.
34
+ * Example: "#/projects/1"
35
+ */
36
+ path: string | string[];
37
+ /**
38
+ * The schema rule description, which is included for certain errors where
39
+ * this information is useful (e.g. to describe a constraint).
40
+ */
41
+ title?: string;
42
+ description?: string;
43
+ /**
44
+ * Returns details for sub-schemas that failed to match. For example, if the schema
45
+ * uses the "oneOf" constraint to accept several alternative possibilities, each
46
+ * alternative will have its own inner detail object explaining why it failed to match.
47
+ */
48
+ inner?: SchemaErrorDetail[];
49
+ schemaId?: string;
50
+ }
51
+ interface ReportOptions {
52
+ maxErrors?: number;
53
+ }
54
+ type TaskResult = unknown;
55
+ type TaskFn = (...args: unknown[]) => TaskResult;
56
+ type TaskFnArgs = Parameters<TaskFn>;
57
+ type TaskProcessFn = (result: ReturnType<TaskFn>) => void;
58
+ type AsyncTask = [TaskFn, TaskFnArgs, TaskProcessFn];
59
+ declare class Report {
60
+ errors: SchemaErrorDetail[];
61
+ parentReport?: Report;
62
+ options: ZSchemaOptions;
63
+ reportOptions: ReportOptions;
64
+ path: string[];
65
+ asyncTasks: AsyncTask[];
66
+ rootSchema?: {
67
+ id?: string;
68
+ };
69
+ commonErrorMessage?: string;
70
+ json?: unknown;
71
+ constructor(parentOrOptions: any, reportOptions?: any);
72
+ isValid(): boolean;
73
+ addAsyncTask(fn: any, args: any, asyncTaskResultProcessFn: any): void;
74
+ getAncestor(id: any): any;
75
+ processAsyncTasks(timeout: any, callback: any): void;
76
+ getPath(returnPathAsString: any): string | any[];
77
+ getSchemaId(): any;
78
+ hasError(errorCode: any, params: any): boolean;
79
+ addError(errorCode: any, params: any, subReports?: any, schema?: any): void;
80
+ getJson(): any;
81
+ addCustomError(errorCode: string, errorMessage: string, params: string[], subReports?: Report[] | Report, schema?: {
82
+ title?: string;
83
+ description?: string;
84
+ }): void;
85
+ }
86
+
87
+ declare const Errors: {
88
+ INVALID_TYPE: string;
89
+ INVALID_FORMAT: string;
90
+ ENUM_MISMATCH: string;
91
+ ENUM_CASE_MISMATCH: string;
92
+ ANY_OF_MISSING: string;
93
+ ONE_OF_MISSING: string;
94
+ ONE_OF_MULTIPLE: string;
95
+ NOT_PASSED: string;
96
+ ARRAY_LENGTH_SHORT: string;
97
+ ARRAY_LENGTH_LONG: string;
98
+ ARRAY_UNIQUE: string;
99
+ ARRAY_ADDITIONAL_ITEMS: string;
100
+ MULTIPLE_OF: string;
101
+ MINIMUM: string;
102
+ MINIMUM_EXCLUSIVE: string;
103
+ MAXIMUM: string;
104
+ MAXIMUM_EXCLUSIVE: string;
105
+ OBJECT_PROPERTIES_MINIMUM: string;
106
+ OBJECT_PROPERTIES_MAXIMUM: string;
107
+ OBJECT_MISSING_REQUIRED_PROPERTY: string;
108
+ OBJECT_ADDITIONAL_PROPERTIES: string;
109
+ OBJECT_DEPENDENCY_KEY: string;
110
+ MIN_LENGTH: string;
111
+ MAX_LENGTH: string;
112
+ PATTERN: string;
113
+ KEYWORD_TYPE_EXPECTED: string;
114
+ KEYWORD_UNDEFINED_STRICT: string;
115
+ KEYWORD_UNEXPECTED: string;
116
+ KEYWORD_MUST_BE: string;
117
+ KEYWORD_DEPENDENCY: string;
118
+ KEYWORD_PATTERN: string;
119
+ KEYWORD_VALUE_TYPE: string;
120
+ UNKNOWN_FORMAT: string;
121
+ CUSTOM_MODE_FORCE_PROPERTIES: string;
122
+ REF_UNRESOLVED: string;
123
+ UNRESOLVABLE_REFERENCE: string;
124
+ SCHEMA_NOT_REACHABLE: string;
125
+ SCHEMA_TYPE_EXPECTED: string;
126
+ SCHEMA_NOT_AN_OBJECT: string;
127
+ ASYNC_TIMEOUT: string;
128
+ PARENT_SCHEMA_VALIDATION_FAILED: string;
129
+ REMOTE_NOT_VALID: string;
130
+ };
131
+
132
+ interface ZSchemaOptions {
133
+ asyncTimeout?: number;
134
+ forceAdditional?: boolean;
135
+ assumeAdditional?: boolean;
136
+ forceItems?: boolean;
137
+ forceMinItems?: boolean;
138
+ forceMaxItems?: boolean;
139
+ forceMinLength?: boolean;
140
+ forceMaxLength?: boolean;
141
+ forceProperties?: boolean;
142
+ ignoreUnresolvableReferences?: boolean;
143
+ noExtraKeywords?: boolean;
144
+ noTypeless?: boolean;
145
+ noEmptyStrings?: boolean;
146
+ noEmptyArrays?: boolean;
147
+ strictUris?: boolean;
148
+ strictMode?: boolean;
149
+ reportPathAsArray?: boolean;
150
+ breakOnFirstError?: boolean;
151
+ pedanticCheck?: boolean;
152
+ ignoreUnknownFormats?: boolean;
153
+ customValidator?: (report: Report, schema: unknown, json: unknown) => void;
154
+ }
155
+ interface ValidateOptions {
156
+ schemaPath?: string;
157
+ includeErrors?: Array<keyof typeof Errors>;
158
+ }
159
+ type ValidateCallback = (e: Error, valid: boolean) => void;
160
+ type SchemaReader = (uri: string) => unknown;
161
+ declare class ZSchema {
162
+ lastReport: Report | undefined;
163
+ /**
164
+ * Register a custom format.
165
+ *
166
+ * @param name - name of the custom format
167
+ * @param validatorFunction - custom format validator function.
168
+ * Returns `true` if `value` matches the custom format.
169
+ */
170
+ static registerFormat(formatName: string, validatorFunction: (value: unknown) => boolean): void;
171
+ /**
172
+ * Unregister a format.
173
+ *
174
+ * @param name - name of the custom format
175
+ */
176
+ static unregisterFormat(name: string): void;
177
+ /**
178
+ * Get the list of all registered formats.
179
+ *
180
+ * Both the names of the burned-in formats and the custom format names are
181
+ * returned by this function.
182
+ *
183
+ * @returns {string[]} the list of all registered format names.
184
+ */
185
+ static getRegisteredFormats(): string[];
186
+ static getDefaultOptions(): ZSchemaOptions;
187
+ private cache;
188
+ private referenceCache;
189
+ private validateOptions;
190
+ options: ZSchemaOptions;
191
+ constructor(options?: ZSchemaOptions);
192
+ /**
193
+ * @param schema - JSON object representing schema
194
+ * @returns {boolean} true if schema is valid.
195
+ */
196
+ validateSchema(schema: unknown): boolean;
197
+ /**
198
+ * @param json - either a JSON string or a parsed JSON object
199
+ * @param schema - the JSON object representing the schema
200
+ * @returns true if json matches schema
201
+ */
202
+ validate(json: any, schema: any, options?: ValidateOptions, callback?: ValidateCallback): boolean;
203
+ validate(json: any, schema: any, callback?: any): boolean;
204
+ validate(json: any, schema: any): boolean;
205
+ /**
206
+ * Returns an Error object for the most recent failed validation, or null if the validation was successful.
207
+ */
208
+ getLastError(): SchemaError;
209
+ /**
210
+ * Returns the error details for the most recent validation, or undefined if the validation was successful.
211
+ * This is the same list as the SchemaError.details property.
212
+ */
213
+ getLastErrors(): SchemaErrorDetail[];
214
+ setRemoteReference(uri: any, schema: any, validationOptions: any): void;
215
+ compileSchema(schema: any): boolean;
216
+ getMissingReferences(arr?: any): any[];
217
+ getMissingRemoteReferences(): any[];
218
+ getResolvedSchema(schema: any): any;
219
+ static schemaReader: SchemaReader;
220
+ setSchemaReader(schemaReader: any): void;
221
+ getSchemaReader(): SchemaReader;
222
+ static setSchemaReader(schemaReader: any): void;
223
+ static schemaSymbol: symbol;
224
+ static jsonSymbol: symbol;
225
+ }
226
+
227
+ export { ZSchema as default };