z-schema 7.0.0 → 7.0.5
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 +7 -2
- package/bin/z-schema +0 -0
- package/cjs/index.d.ts +2 -0
- package/cjs/index.js +260 -256
- package/dist/SchemaCache.js +1 -2
- package/dist/ZSchema.js +4 -0
- package/dist/types/ZSchema.d.ts +2 -0
- package/package.json +3 -2
- package/src/SchemaCache.ts +1 -2
- package/src/ZSchema.ts +5 -0
- package/umd/ZSchema.js +260 -256
- package/umd/ZSchema.min.js +1 -1
package/src/ZSchema.ts
CHANGED
|
@@ -198,6 +198,11 @@ export class ZSchema {
|
|
|
198
198
|
this.setRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, metaschemaOptions);
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
/** Used by SchemaCache to break circular dependency with SchemaCompilation */
|
|
202
|
+
_compileSchema(report: Report, schema: unknown): boolean {
|
|
203
|
+
return SchemaCompilation.compileSchema.call(this, report, schema);
|
|
204
|
+
}
|
|
205
|
+
|
|
201
206
|
/**
|
|
202
207
|
* @param schema - JSON object representing schema
|
|
203
208
|
* @returns {boolean} true if schema is valid.
|
package/umd/ZSchema.js
CHANGED
|
@@ -11976,257 +11976,6 @@
|
|
|
11976
11976
|
var lodash_isequalExports = requireLodash_isequal();
|
|
11977
11977
|
var isequal = /*@__PURE__*/getDefaultExportFromCjs(lodash_isequalExports);
|
|
11978
11978
|
|
|
11979
|
-
function mergeReference(scope, ref) {
|
|
11980
|
-
if (isAbsoluteUri(ref)) {
|
|
11981
|
-
return ref;
|
|
11982
|
-
}
|
|
11983
|
-
let joinedScope = scope.join('');
|
|
11984
|
-
const isScopeAbsolute = isAbsoluteUri(joinedScope);
|
|
11985
|
-
const isScopeRelative = isRelativeUri(joinedScope);
|
|
11986
|
-
const isRefRelative = isRelativeUri(ref);
|
|
11987
|
-
let toRemove;
|
|
11988
|
-
if (isScopeAbsolute && isRefRelative) {
|
|
11989
|
-
toRemove = joinedScope.match(/\/[^/]*$/);
|
|
11990
|
-
if (toRemove) {
|
|
11991
|
-
joinedScope = joinedScope.slice(0, toRemove.index + 1);
|
|
11992
|
-
}
|
|
11993
|
-
}
|
|
11994
|
-
else if (isScopeRelative && isRefRelative) {
|
|
11995
|
-
joinedScope = '';
|
|
11996
|
-
}
|
|
11997
|
-
else {
|
|
11998
|
-
toRemove = joinedScope.match(/[^#/]+$/);
|
|
11999
|
-
if (toRemove) {
|
|
12000
|
-
joinedScope = joinedScope.slice(0, toRemove.index);
|
|
12001
|
-
}
|
|
12002
|
-
}
|
|
12003
|
-
let res = joinedScope + ref;
|
|
12004
|
-
res = res.replace(/##/, '#');
|
|
12005
|
-
return res;
|
|
12006
|
-
}
|
|
12007
|
-
function collectReferences(obj, results, scope, path) {
|
|
12008
|
-
results = results || [];
|
|
12009
|
-
scope = scope || [];
|
|
12010
|
-
path = path || [];
|
|
12011
|
-
if (typeof obj !== 'object' || obj === null) {
|
|
12012
|
-
return results;
|
|
12013
|
-
}
|
|
12014
|
-
if (typeof obj.id === 'string') {
|
|
12015
|
-
scope.push(obj.id);
|
|
12016
|
-
}
|
|
12017
|
-
if (typeof obj.$ref === 'string' && typeof obj.__$refResolved === 'undefined') {
|
|
12018
|
-
results.push({
|
|
12019
|
-
ref: mergeReference(scope, obj.$ref),
|
|
12020
|
-
key: '$ref',
|
|
12021
|
-
obj: obj,
|
|
12022
|
-
path: path.slice(0),
|
|
12023
|
-
});
|
|
12024
|
-
}
|
|
12025
|
-
if (typeof obj.$schema === 'string' && typeof obj.__$schemaResolved === 'undefined') {
|
|
12026
|
-
results.push({
|
|
12027
|
-
ref: mergeReference(scope, obj.$schema),
|
|
12028
|
-
key: '$schema',
|
|
12029
|
-
obj: obj,
|
|
12030
|
-
path: path.slice(0),
|
|
12031
|
-
});
|
|
12032
|
-
}
|
|
12033
|
-
let idx;
|
|
12034
|
-
if (Array.isArray(obj)) {
|
|
12035
|
-
idx = obj.length;
|
|
12036
|
-
while (idx--) {
|
|
12037
|
-
path.push(idx.toString());
|
|
12038
|
-
collectReferences(obj[idx], results, scope, path);
|
|
12039
|
-
path.pop();
|
|
12040
|
-
}
|
|
12041
|
-
}
|
|
12042
|
-
else {
|
|
12043
|
-
const keys = Object.keys(obj);
|
|
12044
|
-
idx = keys.length;
|
|
12045
|
-
while (idx--) {
|
|
12046
|
-
// do not recurse through resolved references and other z-schema props
|
|
12047
|
-
if (keys[idx].indexOf('__$') === 0) {
|
|
12048
|
-
continue;
|
|
12049
|
-
}
|
|
12050
|
-
path.push(keys[idx]);
|
|
12051
|
-
collectReferences(obj[keys[idx]], results, scope, path);
|
|
12052
|
-
path.pop();
|
|
12053
|
-
}
|
|
12054
|
-
}
|
|
12055
|
-
if (typeof obj.id === 'string') {
|
|
12056
|
-
scope.pop();
|
|
12057
|
-
}
|
|
12058
|
-
return results;
|
|
12059
|
-
}
|
|
12060
|
-
const compileArrayOfSchemasLoop = function (mainReport, arr) {
|
|
12061
|
-
let idx = arr.length, compiledCount = 0;
|
|
12062
|
-
while (idx--) {
|
|
12063
|
-
// try to compile each schema separately
|
|
12064
|
-
const report = new Report(mainReport);
|
|
12065
|
-
const isValid = compileSchema.call(this, report, arr[idx]);
|
|
12066
|
-
if (isValid) {
|
|
12067
|
-
compiledCount++;
|
|
12068
|
-
}
|
|
12069
|
-
// copy errors to report
|
|
12070
|
-
mainReport.errors = mainReport.errors.concat(report.errors);
|
|
12071
|
-
}
|
|
12072
|
-
return compiledCount;
|
|
12073
|
-
};
|
|
12074
|
-
function findId$1(arr, id) {
|
|
12075
|
-
let idx = arr.length;
|
|
12076
|
-
while (idx--) {
|
|
12077
|
-
if (arr[idx].id === id) {
|
|
12078
|
-
return arr[idx];
|
|
12079
|
-
}
|
|
12080
|
-
}
|
|
12081
|
-
return null;
|
|
12082
|
-
}
|
|
12083
|
-
const compileArrayOfSchemas = function (report, arr) {
|
|
12084
|
-
let compiled = 0, lastLoopCompiled;
|
|
12085
|
-
do {
|
|
12086
|
-
// remove all UNRESOLVABLE_REFERENCE errors before compiling array again
|
|
12087
|
-
let idx = report.errors.length;
|
|
12088
|
-
while (idx--) {
|
|
12089
|
-
if (report.errors[idx].code === 'UNRESOLVABLE_REFERENCE') {
|
|
12090
|
-
report.errors.splice(idx, 1);
|
|
12091
|
-
}
|
|
12092
|
-
}
|
|
12093
|
-
// remember how many were compiled in the last loop
|
|
12094
|
-
lastLoopCompiled = compiled;
|
|
12095
|
-
// count how many are compiled now
|
|
12096
|
-
compiled = compileArrayOfSchemasLoop.call(this, report, arr);
|
|
12097
|
-
// fix __$missingReferences if possible
|
|
12098
|
-
idx = arr.length;
|
|
12099
|
-
while (idx--) {
|
|
12100
|
-
const sch = arr[idx];
|
|
12101
|
-
if (sch.__$missingReferences) {
|
|
12102
|
-
let idx2 = sch.__$missingReferences.length;
|
|
12103
|
-
while (idx2--) {
|
|
12104
|
-
const refObj = sch.__$missingReferences[idx2];
|
|
12105
|
-
const response = findId$1(arr, refObj.ref);
|
|
12106
|
-
if (response) {
|
|
12107
|
-
// this might create circular references
|
|
12108
|
-
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
12109
|
-
// it's resolved now so delete it
|
|
12110
|
-
sch.__$missingReferences.splice(idx2, 1);
|
|
12111
|
-
}
|
|
12112
|
-
}
|
|
12113
|
-
if (sch.__$missingReferences.length === 0) {
|
|
12114
|
-
delete sch.__$missingReferences;
|
|
12115
|
-
}
|
|
12116
|
-
}
|
|
12117
|
-
}
|
|
12118
|
-
// keep repeating if not all compiled and at least one more was compiled in the last loop
|
|
12119
|
-
} while (compiled !== arr.length && compiled !== lastLoopCompiled);
|
|
12120
|
-
return report.isValid();
|
|
12121
|
-
};
|
|
12122
|
-
function compileSchema(report, schema) {
|
|
12123
|
-
report.commonErrorMessage = 'SCHEMA_COMPILATION_FAILED';
|
|
12124
|
-
// if schema is a string, assume it's a uri
|
|
12125
|
-
if (typeof schema === 'string') {
|
|
12126
|
-
const loadedSchema = getSchemaByUri.call(this, report, schema);
|
|
12127
|
-
if (!loadedSchema) {
|
|
12128
|
-
report.addError('SCHEMA_NOT_REACHABLE', [schema]);
|
|
12129
|
-
return false;
|
|
12130
|
-
}
|
|
12131
|
-
schema = loadedSchema;
|
|
12132
|
-
}
|
|
12133
|
-
// if schema is an array, assume it's an array of schemas
|
|
12134
|
-
if (Array.isArray(schema)) {
|
|
12135
|
-
return compileArrayOfSchemas.call(this, report, schema);
|
|
12136
|
-
}
|
|
12137
|
-
// if we have an id than it should be cached already (if this instance has compiled it)
|
|
12138
|
-
if (schema.__$compiled && schema.id && checkCacheForUri.call(this, schema.id) === false) {
|
|
12139
|
-
schema.__$compiled = undefined;
|
|
12140
|
-
}
|
|
12141
|
-
// do not re-compile schemas
|
|
12142
|
-
if (schema.__$compiled) {
|
|
12143
|
-
return true;
|
|
12144
|
-
}
|
|
12145
|
-
if (schema.id && typeof schema.id === 'string') {
|
|
12146
|
-
// add this to our schemaCache (before compilation in case we have references including id)
|
|
12147
|
-
cacheSchemaByUri.call(this, schema.id, schema);
|
|
12148
|
-
}
|
|
12149
|
-
// this method can be called recursively, so we need to remember our root
|
|
12150
|
-
let isRoot = false;
|
|
12151
|
-
if (!report.rootSchema) {
|
|
12152
|
-
report.rootSchema = schema;
|
|
12153
|
-
isRoot = true;
|
|
12154
|
-
}
|
|
12155
|
-
// delete all __$missingReferences from previous compilation attempts
|
|
12156
|
-
const isValidExceptReferences = report.isValid();
|
|
12157
|
-
delete schema.__$missingReferences;
|
|
12158
|
-
// collect all references that need to be resolved - $ref and $schema
|
|
12159
|
-
const refs = collectReferences.call(this, schema);
|
|
12160
|
-
let idx = refs.length;
|
|
12161
|
-
while (idx--) {
|
|
12162
|
-
// resolve all the collected references into __xxxResolved pointer
|
|
12163
|
-
const refObj = refs[idx];
|
|
12164
|
-
let response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
12165
|
-
// we can try to use custom schemaReader if available
|
|
12166
|
-
if (!response) {
|
|
12167
|
-
const schemaReader = this.getSchemaReader();
|
|
12168
|
-
if (schemaReader) {
|
|
12169
|
-
// it's supposed to return a valid schema
|
|
12170
|
-
const s = schemaReader(refObj.ref);
|
|
12171
|
-
if (s) {
|
|
12172
|
-
// it needs to have the id
|
|
12173
|
-
s.id = refObj.ref;
|
|
12174
|
-
// try to compile the schema
|
|
12175
|
-
const subreport = new Report(report);
|
|
12176
|
-
if (!compileSchema.call(this, subreport, s)) {
|
|
12177
|
-
// copy errors to report
|
|
12178
|
-
report.errors = report.errors.concat(subreport.errors);
|
|
12179
|
-
}
|
|
12180
|
-
else {
|
|
12181
|
-
response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
12182
|
-
}
|
|
12183
|
-
}
|
|
12184
|
-
}
|
|
12185
|
-
}
|
|
12186
|
-
if (!response) {
|
|
12187
|
-
const hasNotValid = report.hasError('REMOTE_NOT_VALID', [refObj.ref]);
|
|
12188
|
-
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
12189
|
-
let isDownloaded = false;
|
|
12190
|
-
const ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;
|
|
12191
|
-
if (isAbsolute) {
|
|
12192
|
-
// we shouldn't add UNRESOLVABLE_REFERENCE for schemas we already have downloaded
|
|
12193
|
-
// and set through setRemoteReference method
|
|
12194
|
-
isDownloaded = checkCacheForUri.call(this, refObj.ref);
|
|
12195
|
-
}
|
|
12196
|
-
if (hasNotValid) ;
|
|
12197
|
-
else if (ignoreUnresolvableRemotes && isAbsolute) ;
|
|
12198
|
-
else if (isDownloaded) ;
|
|
12199
|
-
else {
|
|
12200
|
-
Array.prototype.push.apply(report.path, refObj.path);
|
|
12201
|
-
report.addError('UNRESOLVABLE_REFERENCE', [refObj.ref]);
|
|
12202
|
-
report.path = report.path.slice(0, -refObj.path.length);
|
|
12203
|
-
// pusblish unresolved references out
|
|
12204
|
-
if (isValidExceptReferences) {
|
|
12205
|
-
schema.__$missingReferences = schema.__$missingReferences || [];
|
|
12206
|
-
schema.__$missingReferences.push(refObj);
|
|
12207
|
-
}
|
|
12208
|
-
}
|
|
12209
|
-
}
|
|
12210
|
-
// this might create circular references
|
|
12211
|
-
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
12212
|
-
}
|
|
12213
|
-
const isValid = report.isValid();
|
|
12214
|
-
if (isValid) {
|
|
12215
|
-
schema.__$compiled = true;
|
|
12216
|
-
}
|
|
12217
|
-
else {
|
|
12218
|
-
if (schema.id && typeof schema.id === 'string') {
|
|
12219
|
-
// remove this schema from schemaCache because it failed to compile
|
|
12220
|
-
removeFromCacheByUri.call(this, schema.id);
|
|
12221
|
-
}
|
|
12222
|
-
}
|
|
12223
|
-
// we don't need the root pointer anymore
|
|
12224
|
-
if (isRoot) {
|
|
12225
|
-
report.rootSchema = undefined;
|
|
12226
|
-
}
|
|
12227
|
-
return isValid;
|
|
12228
|
-
}
|
|
12229
|
-
|
|
12230
11979
|
const SchemaValidators = {
|
|
12231
11980
|
$ref: function (report, schema) {
|
|
12232
11981
|
// http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
|
|
@@ -12872,7 +12621,7 @@
|
|
|
12872
12621
|
// if (res && res[0] === "/") { res = res.slice(1); }
|
|
12873
12622
|
return res;
|
|
12874
12623
|
}
|
|
12875
|
-
function findId(schema, id) {
|
|
12624
|
+
function findId$1(schema, id) {
|
|
12876
12625
|
// process only arrays and objects
|
|
12877
12626
|
if (typeof schema !== 'object' || schema === null) {
|
|
12878
12627
|
return;
|
|
@@ -12890,7 +12639,7 @@
|
|
|
12890
12639
|
if (Array.isArray(schema)) {
|
|
12891
12640
|
idx = schema.length;
|
|
12892
12641
|
while (idx--) {
|
|
12893
|
-
result = findId(schema[idx], id);
|
|
12642
|
+
result = findId$1(schema[idx], id);
|
|
12894
12643
|
if (result) {
|
|
12895
12644
|
return result;
|
|
12896
12645
|
}
|
|
@@ -12904,7 +12653,7 @@
|
|
|
12904
12653
|
if (k.indexOf('__$') === 0) {
|
|
12905
12654
|
continue;
|
|
12906
12655
|
}
|
|
12907
|
-
result = findId(schema[k], id);
|
|
12656
|
+
result = findId$1(schema[k], id);
|
|
12908
12657
|
if (result) {
|
|
12909
12658
|
return result;
|
|
12910
12659
|
}
|
|
@@ -12984,7 +12733,7 @@
|
|
|
12984
12733
|
}
|
|
12985
12734
|
else {
|
|
12986
12735
|
remoteReport = new Report(report);
|
|
12987
|
-
if (
|
|
12736
|
+
if (this._compileSchema(remoteReport, result)) {
|
|
12988
12737
|
const savedOptions = this.options;
|
|
12989
12738
|
try {
|
|
12990
12739
|
// If custom validationOptions were provided to setRemoteReference(),
|
|
@@ -13013,7 +12762,7 @@
|
|
|
13013
12762
|
const key = decodeJSONPointer(parts[idx]);
|
|
13014
12763
|
if (idx === 0) {
|
|
13015
12764
|
// it's an id
|
|
13016
|
-
result = findId(result, key);
|
|
12765
|
+
result = findId$1(result, key);
|
|
13017
12766
|
}
|
|
13018
12767
|
else {
|
|
13019
12768
|
// it's a path behind id
|
|
@@ -13024,6 +12773,257 @@
|
|
|
13024
12773
|
return result;
|
|
13025
12774
|
}
|
|
13026
12775
|
|
|
12776
|
+
function mergeReference(scope, ref) {
|
|
12777
|
+
if (isAbsoluteUri(ref)) {
|
|
12778
|
+
return ref;
|
|
12779
|
+
}
|
|
12780
|
+
let joinedScope = scope.join('');
|
|
12781
|
+
const isScopeAbsolute = isAbsoluteUri(joinedScope);
|
|
12782
|
+
const isScopeRelative = isRelativeUri(joinedScope);
|
|
12783
|
+
const isRefRelative = isRelativeUri(ref);
|
|
12784
|
+
let toRemove;
|
|
12785
|
+
if (isScopeAbsolute && isRefRelative) {
|
|
12786
|
+
toRemove = joinedScope.match(/\/[^/]*$/);
|
|
12787
|
+
if (toRemove) {
|
|
12788
|
+
joinedScope = joinedScope.slice(0, toRemove.index + 1);
|
|
12789
|
+
}
|
|
12790
|
+
}
|
|
12791
|
+
else if (isScopeRelative && isRefRelative) {
|
|
12792
|
+
joinedScope = '';
|
|
12793
|
+
}
|
|
12794
|
+
else {
|
|
12795
|
+
toRemove = joinedScope.match(/[^#/]+$/);
|
|
12796
|
+
if (toRemove) {
|
|
12797
|
+
joinedScope = joinedScope.slice(0, toRemove.index);
|
|
12798
|
+
}
|
|
12799
|
+
}
|
|
12800
|
+
let res = joinedScope + ref;
|
|
12801
|
+
res = res.replace(/##/, '#');
|
|
12802
|
+
return res;
|
|
12803
|
+
}
|
|
12804
|
+
function collectReferences(obj, results, scope, path) {
|
|
12805
|
+
results = results || [];
|
|
12806
|
+
scope = scope || [];
|
|
12807
|
+
path = path || [];
|
|
12808
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
12809
|
+
return results;
|
|
12810
|
+
}
|
|
12811
|
+
if (typeof obj.id === 'string') {
|
|
12812
|
+
scope.push(obj.id);
|
|
12813
|
+
}
|
|
12814
|
+
if (typeof obj.$ref === 'string' && typeof obj.__$refResolved === 'undefined') {
|
|
12815
|
+
results.push({
|
|
12816
|
+
ref: mergeReference(scope, obj.$ref),
|
|
12817
|
+
key: '$ref',
|
|
12818
|
+
obj: obj,
|
|
12819
|
+
path: path.slice(0),
|
|
12820
|
+
});
|
|
12821
|
+
}
|
|
12822
|
+
if (typeof obj.$schema === 'string' && typeof obj.__$schemaResolved === 'undefined') {
|
|
12823
|
+
results.push({
|
|
12824
|
+
ref: mergeReference(scope, obj.$schema),
|
|
12825
|
+
key: '$schema',
|
|
12826
|
+
obj: obj,
|
|
12827
|
+
path: path.slice(0),
|
|
12828
|
+
});
|
|
12829
|
+
}
|
|
12830
|
+
let idx;
|
|
12831
|
+
if (Array.isArray(obj)) {
|
|
12832
|
+
idx = obj.length;
|
|
12833
|
+
while (idx--) {
|
|
12834
|
+
path.push(idx.toString());
|
|
12835
|
+
collectReferences(obj[idx], results, scope, path);
|
|
12836
|
+
path.pop();
|
|
12837
|
+
}
|
|
12838
|
+
}
|
|
12839
|
+
else {
|
|
12840
|
+
const keys = Object.keys(obj);
|
|
12841
|
+
idx = keys.length;
|
|
12842
|
+
while (idx--) {
|
|
12843
|
+
// do not recurse through resolved references and other z-schema props
|
|
12844
|
+
if (keys[idx].indexOf('__$') === 0) {
|
|
12845
|
+
continue;
|
|
12846
|
+
}
|
|
12847
|
+
path.push(keys[idx]);
|
|
12848
|
+
collectReferences(obj[keys[idx]], results, scope, path);
|
|
12849
|
+
path.pop();
|
|
12850
|
+
}
|
|
12851
|
+
}
|
|
12852
|
+
if (typeof obj.id === 'string') {
|
|
12853
|
+
scope.pop();
|
|
12854
|
+
}
|
|
12855
|
+
return results;
|
|
12856
|
+
}
|
|
12857
|
+
const compileArrayOfSchemasLoop = function (mainReport, arr) {
|
|
12858
|
+
let idx = arr.length, compiledCount = 0;
|
|
12859
|
+
while (idx--) {
|
|
12860
|
+
// try to compile each schema separately
|
|
12861
|
+
const report = new Report(mainReport);
|
|
12862
|
+
const isValid = compileSchema.call(this, report, arr[idx]);
|
|
12863
|
+
if (isValid) {
|
|
12864
|
+
compiledCount++;
|
|
12865
|
+
}
|
|
12866
|
+
// copy errors to report
|
|
12867
|
+
mainReport.errors = mainReport.errors.concat(report.errors);
|
|
12868
|
+
}
|
|
12869
|
+
return compiledCount;
|
|
12870
|
+
};
|
|
12871
|
+
function findId(arr, id) {
|
|
12872
|
+
let idx = arr.length;
|
|
12873
|
+
while (idx--) {
|
|
12874
|
+
if (arr[idx].id === id) {
|
|
12875
|
+
return arr[idx];
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
return null;
|
|
12879
|
+
}
|
|
12880
|
+
const compileArrayOfSchemas = function (report, arr) {
|
|
12881
|
+
let compiled = 0, lastLoopCompiled;
|
|
12882
|
+
do {
|
|
12883
|
+
// remove all UNRESOLVABLE_REFERENCE errors before compiling array again
|
|
12884
|
+
let idx = report.errors.length;
|
|
12885
|
+
while (idx--) {
|
|
12886
|
+
if (report.errors[idx].code === 'UNRESOLVABLE_REFERENCE') {
|
|
12887
|
+
report.errors.splice(idx, 1);
|
|
12888
|
+
}
|
|
12889
|
+
}
|
|
12890
|
+
// remember how many were compiled in the last loop
|
|
12891
|
+
lastLoopCompiled = compiled;
|
|
12892
|
+
// count how many are compiled now
|
|
12893
|
+
compiled = compileArrayOfSchemasLoop.call(this, report, arr);
|
|
12894
|
+
// fix __$missingReferences if possible
|
|
12895
|
+
idx = arr.length;
|
|
12896
|
+
while (idx--) {
|
|
12897
|
+
const sch = arr[idx];
|
|
12898
|
+
if (sch.__$missingReferences) {
|
|
12899
|
+
let idx2 = sch.__$missingReferences.length;
|
|
12900
|
+
while (idx2--) {
|
|
12901
|
+
const refObj = sch.__$missingReferences[idx2];
|
|
12902
|
+
const response = findId(arr, refObj.ref);
|
|
12903
|
+
if (response) {
|
|
12904
|
+
// this might create circular references
|
|
12905
|
+
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
12906
|
+
// it's resolved now so delete it
|
|
12907
|
+
sch.__$missingReferences.splice(idx2, 1);
|
|
12908
|
+
}
|
|
12909
|
+
}
|
|
12910
|
+
if (sch.__$missingReferences.length === 0) {
|
|
12911
|
+
delete sch.__$missingReferences;
|
|
12912
|
+
}
|
|
12913
|
+
}
|
|
12914
|
+
}
|
|
12915
|
+
// keep repeating if not all compiled and at least one more was compiled in the last loop
|
|
12916
|
+
} while (compiled !== arr.length && compiled !== lastLoopCompiled);
|
|
12917
|
+
return report.isValid();
|
|
12918
|
+
};
|
|
12919
|
+
function compileSchema(report, schema) {
|
|
12920
|
+
report.commonErrorMessage = 'SCHEMA_COMPILATION_FAILED';
|
|
12921
|
+
// if schema is a string, assume it's a uri
|
|
12922
|
+
if (typeof schema === 'string') {
|
|
12923
|
+
const loadedSchema = getSchemaByUri.call(this, report, schema);
|
|
12924
|
+
if (!loadedSchema) {
|
|
12925
|
+
report.addError('SCHEMA_NOT_REACHABLE', [schema]);
|
|
12926
|
+
return false;
|
|
12927
|
+
}
|
|
12928
|
+
schema = loadedSchema;
|
|
12929
|
+
}
|
|
12930
|
+
// if schema is an array, assume it's an array of schemas
|
|
12931
|
+
if (Array.isArray(schema)) {
|
|
12932
|
+
return compileArrayOfSchemas.call(this, report, schema);
|
|
12933
|
+
}
|
|
12934
|
+
// if we have an id than it should be cached already (if this instance has compiled it)
|
|
12935
|
+
if (schema.__$compiled && schema.id && checkCacheForUri.call(this, schema.id) === false) {
|
|
12936
|
+
schema.__$compiled = undefined;
|
|
12937
|
+
}
|
|
12938
|
+
// do not re-compile schemas
|
|
12939
|
+
if (schema.__$compiled) {
|
|
12940
|
+
return true;
|
|
12941
|
+
}
|
|
12942
|
+
if (schema.id && typeof schema.id === 'string') {
|
|
12943
|
+
// add this to our schemaCache (before compilation in case we have references including id)
|
|
12944
|
+
cacheSchemaByUri.call(this, schema.id, schema);
|
|
12945
|
+
}
|
|
12946
|
+
// this method can be called recursively, so we need to remember our root
|
|
12947
|
+
let isRoot = false;
|
|
12948
|
+
if (!report.rootSchema) {
|
|
12949
|
+
report.rootSchema = schema;
|
|
12950
|
+
isRoot = true;
|
|
12951
|
+
}
|
|
12952
|
+
// delete all __$missingReferences from previous compilation attempts
|
|
12953
|
+
const isValidExceptReferences = report.isValid();
|
|
12954
|
+
delete schema.__$missingReferences;
|
|
12955
|
+
// collect all references that need to be resolved - $ref and $schema
|
|
12956
|
+
const refs = collectReferences.call(this, schema);
|
|
12957
|
+
let idx = refs.length;
|
|
12958
|
+
while (idx--) {
|
|
12959
|
+
// resolve all the collected references into __xxxResolved pointer
|
|
12960
|
+
const refObj = refs[idx];
|
|
12961
|
+
let response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
12962
|
+
// we can try to use custom schemaReader if available
|
|
12963
|
+
if (!response) {
|
|
12964
|
+
const schemaReader = this.getSchemaReader();
|
|
12965
|
+
if (schemaReader) {
|
|
12966
|
+
// it's supposed to return a valid schema
|
|
12967
|
+
const s = schemaReader(refObj.ref);
|
|
12968
|
+
if (s) {
|
|
12969
|
+
// it needs to have the id
|
|
12970
|
+
s.id = refObj.ref;
|
|
12971
|
+
// try to compile the schema
|
|
12972
|
+
const subreport = new Report(report);
|
|
12973
|
+
if (!compileSchema.call(this, subreport, s)) {
|
|
12974
|
+
// copy errors to report
|
|
12975
|
+
report.errors = report.errors.concat(subreport.errors);
|
|
12976
|
+
}
|
|
12977
|
+
else {
|
|
12978
|
+
response = getSchemaByUri.call(this, report, refObj.ref, schema);
|
|
12979
|
+
}
|
|
12980
|
+
}
|
|
12981
|
+
}
|
|
12982
|
+
}
|
|
12983
|
+
if (!response) {
|
|
12984
|
+
const hasNotValid = report.hasError('REMOTE_NOT_VALID', [refObj.ref]);
|
|
12985
|
+
const isAbsolute = isAbsoluteUri(refObj.ref);
|
|
12986
|
+
let isDownloaded = false;
|
|
12987
|
+
const ignoreUnresolvableRemotes = this.options.ignoreUnresolvableReferences === true;
|
|
12988
|
+
if (isAbsolute) {
|
|
12989
|
+
// we shouldn't add UNRESOLVABLE_REFERENCE for schemas we already have downloaded
|
|
12990
|
+
// and set through setRemoteReference method
|
|
12991
|
+
isDownloaded = checkCacheForUri.call(this, refObj.ref);
|
|
12992
|
+
}
|
|
12993
|
+
if (hasNotValid) ;
|
|
12994
|
+
else if (ignoreUnresolvableRemotes && isAbsolute) ;
|
|
12995
|
+
else if (isDownloaded) ;
|
|
12996
|
+
else {
|
|
12997
|
+
Array.prototype.push.apply(report.path, refObj.path);
|
|
12998
|
+
report.addError('UNRESOLVABLE_REFERENCE', [refObj.ref]);
|
|
12999
|
+
report.path = report.path.slice(0, -refObj.path.length);
|
|
13000
|
+
// pusblish unresolved references out
|
|
13001
|
+
if (isValidExceptReferences) {
|
|
13002
|
+
schema.__$missingReferences = schema.__$missingReferences || [];
|
|
13003
|
+
schema.__$missingReferences.push(refObj);
|
|
13004
|
+
}
|
|
13005
|
+
}
|
|
13006
|
+
}
|
|
13007
|
+
// this might create circular references
|
|
13008
|
+
refObj.obj['__' + refObj.key + 'Resolved'] = response;
|
|
13009
|
+
}
|
|
13010
|
+
const isValid = report.isValid();
|
|
13011
|
+
if (isValid) {
|
|
13012
|
+
schema.__$compiled = true;
|
|
13013
|
+
}
|
|
13014
|
+
else {
|
|
13015
|
+
if (schema.id && typeof schema.id === 'string') {
|
|
13016
|
+
// remove this schema from schemaCache because it failed to compile
|
|
13017
|
+
removeFromCacheByUri.call(this, schema.id);
|
|
13018
|
+
}
|
|
13019
|
+
}
|
|
13020
|
+
// we don't need the root pointer anymore
|
|
13021
|
+
if (isRoot) {
|
|
13022
|
+
report.rootSchema = undefined;
|
|
13023
|
+
}
|
|
13024
|
+
return isValid;
|
|
13025
|
+
}
|
|
13026
|
+
|
|
13027
13027
|
var id$1 = "http://json-schema.org/draft-04/schema#";
|
|
13028
13028
|
var $schema$1 = "http://json-schema.org/draft-04/schema#";
|
|
13029
13029
|
var description = "Core schema meta-schema";
|
|
@@ -13565,6 +13565,10 @@
|
|
|
13565
13565
|
this.setRemoteReference('http://json-schema.org/draft-04/schema', Draft4Schema, metaschemaOptions);
|
|
13566
13566
|
this.setRemoteReference('http://json-schema.org/draft-04/hyper-schema', Draft4HyperSchema, metaschemaOptions);
|
|
13567
13567
|
}
|
|
13568
|
+
/** Used by SchemaCache to break circular dependency with SchemaCompilation */
|
|
13569
|
+
_compileSchema(report, schema) {
|
|
13570
|
+
return compileSchema.call(this, report, schema);
|
|
13571
|
+
}
|
|
13568
13572
|
/**
|
|
13569
13573
|
* @param schema - JSON object representing schema
|
|
13570
13574
|
* @returns {boolean} true if schema is valid.
|