@aws-cdk/cloud-assembly-schema 40.3.0 → 40.4.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/.jsii +3 -3
- package/lib/manifest.js +1 -1
- package/node_modules/jsonschema/.editorconfig +10 -0
- package/node_modules/jsonschema/LICENSE +21 -0
- package/node_modules/jsonschema/README.md +421 -0
- package/node_modules/jsonschema/lib/attribute.js +978 -0
- package/node_modules/jsonschema/lib/helpers.js +390 -0
- package/node_modules/jsonschema/lib/index.d.ts +142 -0
- package/node_modules/jsonschema/lib/index.js +15 -0
- package/node_modules/jsonschema/lib/scan.js +75 -0
- package/node_modules/jsonschema/lib/validator.js +336 -0
- package/node_modules/jsonschema/package.json +42 -0
- package/package.json +4 -4
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var uri = require('url');
|
|
4
|
+
|
|
5
|
+
var ValidationError = exports.ValidationError = function ValidationError (message, instance, schema, path, name, argument) {
|
|
6
|
+
if(Array.isArray(path)){
|
|
7
|
+
this.path = path;
|
|
8
|
+
this.property = path.reduce(function(sum, item){
|
|
9
|
+
return sum + makeSuffix(item);
|
|
10
|
+
}, 'instance');
|
|
11
|
+
}else if(path !== undefined){
|
|
12
|
+
this.property = path;
|
|
13
|
+
}
|
|
14
|
+
if (message) {
|
|
15
|
+
this.message = message;
|
|
16
|
+
}
|
|
17
|
+
if (schema) {
|
|
18
|
+
var id = schema.$id || schema.id;
|
|
19
|
+
this.schema = id || schema;
|
|
20
|
+
}
|
|
21
|
+
if (instance !== undefined) {
|
|
22
|
+
this.instance = instance;
|
|
23
|
+
}
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.argument = argument;
|
|
26
|
+
this.stack = this.toString();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
ValidationError.prototype.toString = function toString() {
|
|
30
|
+
return this.property + ' ' + this.message;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
var ValidatorResult = exports.ValidatorResult = function ValidatorResult(instance, schema, options, ctx) {
|
|
34
|
+
this.instance = instance;
|
|
35
|
+
this.schema = schema;
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.path = ctx.path;
|
|
38
|
+
this.propertyPath = ctx.propertyPath;
|
|
39
|
+
this.errors = [];
|
|
40
|
+
this.throwError = options && options.throwError;
|
|
41
|
+
this.throwFirst = options && options.throwFirst;
|
|
42
|
+
this.throwAll = options && options.throwAll;
|
|
43
|
+
this.disableFormat = options && options.disableFormat === true;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
ValidatorResult.prototype.addError = function addError(detail) {
|
|
47
|
+
var err;
|
|
48
|
+
if (typeof detail == 'string') {
|
|
49
|
+
err = new ValidationError(detail, this.instance, this.schema, this.path);
|
|
50
|
+
} else {
|
|
51
|
+
if (!detail) throw new Error('Missing error detail');
|
|
52
|
+
if (!detail.message) throw new Error('Missing error message');
|
|
53
|
+
if (!detail.name) throw new Error('Missing validator type');
|
|
54
|
+
err = new ValidationError(detail.message, this.instance, this.schema, this.path, detail.name, detail.argument);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.errors.push(err);
|
|
58
|
+
if (this.throwFirst) {
|
|
59
|
+
throw new ValidatorResultError(this);
|
|
60
|
+
}else if(this.throwError){
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
return err;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
ValidatorResult.prototype.importErrors = function importErrors(res) {
|
|
67
|
+
if (typeof res == 'string' || (res && res.validatorType)) {
|
|
68
|
+
this.addError(res);
|
|
69
|
+
} else if (res && res.errors) {
|
|
70
|
+
this.errors = this.errors.concat(res.errors);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
function stringizer (v,i){
|
|
75
|
+
return i+': '+v.toString()+'\n';
|
|
76
|
+
}
|
|
77
|
+
ValidatorResult.prototype.toString = function toString(res) {
|
|
78
|
+
return this.errors.map(stringizer).join('');
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
Object.defineProperty(ValidatorResult.prototype, "valid", { get: function() {
|
|
82
|
+
return !this.errors.length;
|
|
83
|
+
} });
|
|
84
|
+
|
|
85
|
+
module.exports.ValidatorResultError = ValidatorResultError;
|
|
86
|
+
function ValidatorResultError(result) {
|
|
87
|
+
if(Error.captureStackTrace){
|
|
88
|
+
Error.captureStackTrace(this, ValidatorResultError);
|
|
89
|
+
}
|
|
90
|
+
this.instance = result.instance;
|
|
91
|
+
this.schema = result.schema;
|
|
92
|
+
this.options = result.options;
|
|
93
|
+
this.errors = result.errors;
|
|
94
|
+
}
|
|
95
|
+
ValidatorResultError.prototype = new Error();
|
|
96
|
+
ValidatorResultError.prototype.constructor = ValidatorResultError;
|
|
97
|
+
ValidatorResultError.prototype.name = "Validation Error";
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Describes a problem with a Schema which prevents validation of an instance
|
|
101
|
+
* @name SchemaError
|
|
102
|
+
* @constructor
|
|
103
|
+
*/
|
|
104
|
+
var SchemaError = exports.SchemaError = function SchemaError (msg, schema) {
|
|
105
|
+
this.message = msg;
|
|
106
|
+
this.schema = schema;
|
|
107
|
+
Error.call(this, msg);
|
|
108
|
+
Error.captureStackTrace(this, SchemaError);
|
|
109
|
+
};
|
|
110
|
+
SchemaError.prototype = Object.create(Error.prototype,
|
|
111
|
+
{
|
|
112
|
+
constructor: {value: SchemaError, enumerable: false},
|
|
113
|
+
name: {value: 'SchemaError', enumerable: false},
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
var SchemaContext = exports.SchemaContext = function SchemaContext (schema, options, path, base, schemas) {
|
|
117
|
+
this.schema = schema;
|
|
118
|
+
this.options = options;
|
|
119
|
+
if(Array.isArray(path)){
|
|
120
|
+
this.path = path;
|
|
121
|
+
this.propertyPath = path.reduce(function(sum, item){
|
|
122
|
+
return sum + makeSuffix(item);
|
|
123
|
+
}, 'instance');
|
|
124
|
+
}else{
|
|
125
|
+
this.propertyPath = path;
|
|
126
|
+
}
|
|
127
|
+
this.base = base;
|
|
128
|
+
this.schemas = schemas;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
SchemaContext.prototype.resolve = function resolve (target) {
|
|
132
|
+
return uri.resolve(this.base, target);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
SchemaContext.prototype.makeChild = function makeChild(schema, propertyName){
|
|
136
|
+
var path = (propertyName===undefined) ? this.path : this.path.concat([propertyName]);
|
|
137
|
+
var id = schema.$id || schema.id;
|
|
138
|
+
var base = uri.resolve(this.base, id||'');
|
|
139
|
+
var ctx = new SchemaContext(schema, this.options, path, base, Object.create(this.schemas));
|
|
140
|
+
if(id && !ctx.schemas[base]){
|
|
141
|
+
ctx.schemas[base] = schema;
|
|
142
|
+
}
|
|
143
|
+
return ctx;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
var FORMAT_REGEXPS = exports.FORMAT_REGEXPS = {
|
|
147
|
+
// 7.3.1. Dates, Times, and Duration
|
|
148
|
+
'date-time': /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(3[01]|0[1-9]|[12][0-9])[tT ](2[0-4]|[01][0-9]):([0-5][0-9]):(60|[0-5][0-9])(\.\d+)?([zZ]|[+-]([0-5][0-9]):(60|[0-5][0-9]))$/,
|
|
149
|
+
'date': /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-(3[01]|0[1-9]|[12][0-9])$/,
|
|
150
|
+
'time': /^(2[0-4]|[01][0-9]):([0-5][0-9]):(60|[0-5][0-9])$/,
|
|
151
|
+
'duration': /P(T\d+(H(\d+M(\d+S)?)?|M(\d+S)?|S)|\d+(D|M(\d+D)?|Y(\d+M(\d+D)?)?)(T\d+(H(\d+M(\d+S)?)?|M(\d+S)?|S))?|\d+W)/i,
|
|
152
|
+
|
|
153
|
+
// 7.3.2. Email Addresses
|
|
154
|
+
// TODO: fix the email production
|
|
155
|
+
'email': /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/,
|
|
156
|
+
'idn-email': /^("(?:[!#-\[\]-\u{10FFFF}]|\\[\t -\u{10FFFF}])*"|[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*)@([!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*|\[[!-Z\^-\u{10FFFF}]*\])$/u,
|
|
157
|
+
|
|
158
|
+
// 7.3.3. Hostnames
|
|
159
|
+
|
|
160
|
+
// 7.3.4. IP Addresses
|
|
161
|
+
'ip-address': /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
|
|
162
|
+
// FIXME whitespace is invalid
|
|
163
|
+
'ipv6': /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/,
|
|
164
|
+
|
|
165
|
+
// 7.3.5. Resource Identifiers
|
|
166
|
+
// TODO: A more accurate regular expression for "uri" goes:
|
|
167
|
+
// [A-Za-z][+\-.0-9A-Za-z]*:((/(/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?)?)?#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|(/(/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~])|/?%[0-9A-Fa-f]{2}|[!$&-.0-;=?-Z_a-z~])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*(#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*)?|/(/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+(:\d*)?|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?:\d*|\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)?)?
|
|
168
|
+
'uri': /^[a-zA-Z][a-zA-Z0-9+.-]*:[^\s]*$/,
|
|
169
|
+
'uri-reference': /^(((([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|([A-Za-z][+\-.0-9A-Za-z]*:?)?)|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|(\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?)?))#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|(([A-Za-z][+\-.0-9A-Za-z]*)?%[0-9A-Fa-f]{2}|[!$&-.0-9;=@_~]|[A-Za-z][+\-.0-9A-Za-z]*[!$&-*,;=@_~])(%[0-9A-Fa-f]{2}|[!$&-.0-9;=@-Z_a-z~])*((([/?](%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*)?#|[/?])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*)?|([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~])*|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~])+(:\d*)?|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?:\d*|\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~]+)?|[.0-:A-Fa-f]+)\])?)?|[A-Za-z][+\-.0-9A-Za-z]*:?)?$/,
|
|
170
|
+
'iri': /^[a-zA-Z][a-zA-Z0-9+.-]*:[^\s]*$/,
|
|
171
|
+
'iri-reference': /^(((([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~-\u{10FFFF}]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|([A-Za-z][+\-.0-9A-Za-z]*:?)?)|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|(\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?)?))#(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|(([A-Za-z][+\-.0-9A-Za-z]*)?%[0-9A-Fa-f]{2}|[!$&-.0-9;=@_~-\u{10FFFF}]|[A-Za-z][+\-.0-9A-Za-z]*[!$&-*,;=@_~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-.0-9;=@-Z_a-z~-\u{10FFFF}])*((([/?](%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*)?#|[/?])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*)?|([A-Za-z][+\-.0-9A-Za-z]*(:%[0-9A-Fa-f]{2}|:[!$&-.0-;=?-Z_a-z~-\u{10FFFF}]|[/?])|\?)(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|([A-Za-z][+\-.0-9A-Za-z]*:)?\/((%[0-9A-Fa-f]{2}|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)(:\d*)?[/?]|[!$&-.0-;=?-Z_a-z~-\u{10FFFF}])(%[0-9A-Fa-f]{2}|[!$&-;=?-Z_a-z~-\u{10FFFF}])*|\/((%[0-9A-Fa-f]{2}|[!$&-.0-9;=A-Z_a-z~-\u{10FFFF}])+(:\d*)?|(\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?:\d*|\[(([Vv][0-9A-Fa-f]+\.[!$&-.0-;=A-Z_a-z~-\u{10FFFF}]+)?|[.0-:A-Fa-f]+)\])?)?|[A-Za-z][+\-.0-9A-Za-z]*:?)?$/u,
|
|
172
|
+
'uuid': /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i,
|
|
173
|
+
|
|
174
|
+
// 7.3.6. uri-template
|
|
175
|
+
'uri-template': /(%[0-9a-f]{2}|[!#$&(-;=?@\[\]_a-z~]|\{[!#&+,./;=?@|]?(%[0-9a-f]{2}|[0-9_a-z])(\.?(%[0-9a-f]{2}|[0-9_a-z]))*(:[1-9]\d{0,3}|\*)?(,(%[0-9a-f]{2}|[0-9_a-z])(\.?(%[0-9a-f]{2}|[0-9_a-z]))*(:[1-9]\d{0,3}|\*)?)*\})*/iu,
|
|
176
|
+
|
|
177
|
+
// 7.3.7. JSON Pointers
|
|
178
|
+
'json-pointer': /^(\/([\x00-\x2e0-@\[-}\x7f]|~[01])*)*$/iu,
|
|
179
|
+
'relative-json-pointer': /^\d+(#|(\/([\x00-\x2e0-@\[-}\x7f]|~[01])*)*)$/iu,
|
|
180
|
+
|
|
181
|
+
// hostname regex from: http://stackoverflow.com/a/1420225/5628
|
|
182
|
+
'hostname': /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$/,
|
|
183
|
+
'host-name': /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$/,
|
|
184
|
+
|
|
185
|
+
'utc-millisec': function (input) {
|
|
186
|
+
return (typeof input === 'string') && parseFloat(input) === parseInt(input, 10) && !isNaN(input);
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
// 7.3.8. regex
|
|
190
|
+
'regex': function (input) {
|
|
191
|
+
var result = true;
|
|
192
|
+
try {
|
|
193
|
+
new RegExp(input);
|
|
194
|
+
} catch (e) {
|
|
195
|
+
result = false;
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
// Other definitions
|
|
201
|
+
// "style" was removed from JSON Schema in draft-4 and is deprecated
|
|
202
|
+
'style': /[\r\n\t ]*[^\r\n\t ][^:]*:[\r\n\t ]*[^\r\n\t ;]*[\r\n\t ]*;?/,
|
|
203
|
+
// "color" was removed from JSON Schema in draft-4 and is deprecated
|
|
204
|
+
'color': /^(#?([0-9A-Fa-f]{3}){1,2}\b|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\)))$/,
|
|
205
|
+
'phone': /^\+(?:[0-9] ?){6,14}[0-9]$/,
|
|
206
|
+
'alpha': /^[a-zA-Z]+$/,
|
|
207
|
+
'alphanumeric': /^[a-zA-Z0-9]+$/,
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
FORMAT_REGEXPS.regexp = FORMAT_REGEXPS.regex;
|
|
211
|
+
FORMAT_REGEXPS.pattern = FORMAT_REGEXPS.regex;
|
|
212
|
+
FORMAT_REGEXPS.ipv4 = FORMAT_REGEXPS['ip-address'];
|
|
213
|
+
|
|
214
|
+
exports.isFormat = function isFormat (input, format, validator) {
|
|
215
|
+
if (typeof input === 'string' && FORMAT_REGEXPS[format] !== undefined) {
|
|
216
|
+
if (FORMAT_REGEXPS[format] instanceof RegExp) {
|
|
217
|
+
return FORMAT_REGEXPS[format].test(input);
|
|
218
|
+
}
|
|
219
|
+
if (typeof FORMAT_REGEXPS[format] === 'function') {
|
|
220
|
+
return FORMAT_REGEXPS[format](input);
|
|
221
|
+
}
|
|
222
|
+
} else if (validator && validator.customFormats &&
|
|
223
|
+
typeof validator.customFormats[format] === 'function') {
|
|
224
|
+
return validator.customFormats[format](input);
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
var makeSuffix = exports.makeSuffix = function makeSuffix (key) {
|
|
230
|
+
key = key.toString();
|
|
231
|
+
// This function could be capable of outputting valid a ECMAScript string, but the
|
|
232
|
+
// resulting code for testing which form to use would be tens of thousands of characters long
|
|
233
|
+
// That means this will use the name form for some illegal forms
|
|
234
|
+
if (!key.match(/[.\s\[\]]/) && !key.match(/^[\d]/)) {
|
|
235
|
+
return '.' + key;
|
|
236
|
+
}
|
|
237
|
+
if (key.match(/^\d+$/)) {
|
|
238
|
+
return '[' + key + ']';
|
|
239
|
+
}
|
|
240
|
+
return '[' + JSON.stringify(key) + ']';
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
exports.deepCompareStrict = function deepCompareStrict (a, b) {
|
|
244
|
+
if (typeof a !== typeof b) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
if (Array.isArray(a)) {
|
|
248
|
+
if (!Array.isArray(b)) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
if (a.length !== b.length) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
return a.every(function (v, i) {
|
|
255
|
+
return deepCompareStrict(a[i], b[i]);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (typeof a === 'object') {
|
|
259
|
+
if (!a || !b) {
|
|
260
|
+
return a === b;
|
|
261
|
+
}
|
|
262
|
+
var aKeys = Object.keys(a);
|
|
263
|
+
var bKeys = Object.keys(b);
|
|
264
|
+
if (aKeys.length !== bKeys.length) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return aKeys.every(function (v) {
|
|
268
|
+
return deepCompareStrict(a[v], b[v]);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return a === b;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
function deepMerger (target, dst, e, i) {
|
|
275
|
+
if (typeof e === 'object') {
|
|
276
|
+
dst[i] = deepMerge(target[i], e);
|
|
277
|
+
} else {
|
|
278
|
+
if (target.indexOf(e) === -1) {
|
|
279
|
+
dst.push(e);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function copyist (src, dst, key) {
|
|
285
|
+
dst[key] = src[key];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function copyistWithDeepMerge (target, src, dst, key) {
|
|
289
|
+
if (typeof src[key] !== 'object' || !src[key]) {
|
|
290
|
+
dst[key] = src[key];
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
if (!target[key]) {
|
|
294
|
+
dst[key] = src[key];
|
|
295
|
+
} else {
|
|
296
|
+
dst[key] = deepMerge(target[key], src[key]);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function deepMerge (target, src) {
|
|
302
|
+
var array = Array.isArray(src);
|
|
303
|
+
var dst = array && [] || {};
|
|
304
|
+
|
|
305
|
+
if (array) {
|
|
306
|
+
target = target || [];
|
|
307
|
+
dst = dst.concat(target);
|
|
308
|
+
src.forEach(deepMerger.bind(null, target, dst));
|
|
309
|
+
} else {
|
|
310
|
+
if (target && typeof target === 'object') {
|
|
311
|
+
Object.keys(target).forEach(copyist.bind(null, target, dst));
|
|
312
|
+
}
|
|
313
|
+
Object.keys(src).forEach(copyistWithDeepMerge.bind(null, target, src, dst));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return dst;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
module.exports.deepMerge = deepMerge;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Validates instance against the provided schema
|
|
323
|
+
* Implements URI+JSON Pointer encoding, e.g. "%7e"="~0"=>"~", "~1"="%2f"=>"/"
|
|
324
|
+
* @param o
|
|
325
|
+
* @param s The path to walk o along
|
|
326
|
+
* @return any
|
|
327
|
+
*/
|
|
328
|
+
exports.objectGetPath = function objectGetPath(o, s) {
|
|
329
|
+
var parts = s.split('/').slice(1);
|
|
330
|
+
var k;
|
|
331
|
+
while (typeof (k=parts.shift()) == 'string') {
|
|
332
|
+
var n = decodeURIComponent(k.replace(/~0/,'~').replace(/~1/g,'/'));
|
|
333
|
+
if (!(n in o)) return;
|
|
334
|
+
o = o[n];
|
|
335
|
+
}
|
|
336
|
+
return o;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
function pathEncoder (v) {
|
|
340
|
+
return '/'+encodeURIComponent(v).replace(/~/g,'%7E');
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Accept an Array of property names and return a JSON Pointer URI fragment
|
|
344
|
+
* @param Array a
|
|
345
|
+
* @return {String}
|
|
346
|
+
*/
|
|
347
|
+
exports.encodePath = function encodePointer(a){
|
|
348
|
+
// ~ must be encoded explicitly because hacks
|
|
349
|
+
// the slash is encoded by encodeURIComponent
|
|
350
|
+
return a.map(pathEncoder).join('');
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Calculate the number of decimal places a number uses
|
|
356
|
+
* We need this to get correct results out of multipleOf and divisibleBy
|
|
357
|
+
* when either figure is has decimal places, due to IEEE-754 float issues.
|
|
358
|
+
* @param number
|
|
359
|
+
* @returns {number}
|
|
360
|
+
*/
|
|
361
|
+
exports.getDecimalPlaces = function getDecimalPlaces(number) {
|
|
362
|
+
|
|
363
|
+
var decimalPlaces = 0;
|
|
364
|
+
if (isNaN(number)) return decimalPlaces;
|
|
365
|
+
|
|
366
|
+
if (typeof number !== 'number') {
|
|
367
|
+
number = Number(number);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
var parts = number.toString().split('e');
|
|
371
|
+
if (parts.length === 2) {
|
|
372
|
+
if (parts[1][0] !== '-') {
|
|
373
|
+
return decimalPlaces;
|
|
374
|
+
} else {
|
|
375
|
+
decimalPlaces = Number(parts[1].slice(1));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
var decimalParts = parts[0].split('.');
|
|
380
|
+
if (decimalParts.length === 2) {
|
|
381
|
+
decimalPlaces += decimalParts[1].length;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return decimalPlaces;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
exports.isSchema = function isSchema(val){
|
|
388
|
+
return (typeof val === 'object' && val) || (typeof val === 'boolean');
|
|
389
|
+
};
|
|
390
|
+
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/*
|
|
2
|
+
This is type definition for typescript.
|
|
3
|
+
This is for library users. Thus, properties and methods for internal use is omitted.
|
|
4
|
+
*/
|
|
5
|
+
export declare class Validator {
|
|
6
|
+
constructor();
|
|
7
|
+
customFormats: {[formatName: string]: CustomFormat};
|
|
8
|
+
schemas: {[id: string]: Schema};
|
|
9
|
+
unresolvedRefs: string[];
|
|
10
|
+
|
|
11
|
+
attributes: {[property: string]: CustomProperty};
|
|
12
|
+
|
|
13
|
+
addSchema(schema?: Schema, uri?: string): Schema|void;
|
|
14
|
+
validate(instance: any, schema: Schema, options?: Options, ctx?: SchemaContext): ValidatorResult;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export declare class ValidatorResult {
|
|
18
|
+
constructor(instance: any, schema: Schema, options: Options, ctx: SchemaContext)
|
|
19
|
+
instance: any;
|
|
20
|
+
schema: Schema;
|
|
21
|
+
propertyPath: string;
|
|
22
|
+
errors: ValidationError[];
|
|
23
|
+
throwError: boolean;
|
|
24
|
+
disableFormat: boolean;
|
|
25
|
+
valid: boolean;
|
|
26
|
+
addError(detail: string|ErrorDetail): ValidationError;
|
|
27
|
+
toString(): string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export declare class ValidationError {
|
|
31
|
+
constructor(message?: string, instance?: any, schema?: Schema, propertyPath?: any, name?: string, argument?: any);
|
|
32
|
+
path: (string|number)[];
|
|
33
|
+
property: string;
|
|
34
|
+
message: string;
|
|
35
|
+
schema: string|Schema;
|
|
36
|
+
instance: any;
|
|
37
|
+
name: string;
|
|
38
|
+
argument: any;
|
|
39
|
+
toString(): string;
|
|
40
|
+
stack: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export declare class SchemaError extends Error{
|
|
44
|
+
constructor(msg: string, schema: Schema);
|
|
45
|
+
schema: Schema;
|
|
46
|
+
message: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export declare function validate(instance: any, schema: any, options?: Options): ValidatorResult
|
|
50
|
+
|
|
51
|
+
export interface Schema {
|
|
52
|
+
$id?: string
|
|
53
|
+
id?: string
|
|
54
|
+
$schema?: string
|
|
55
|
+
$ref?: string
|
|
56
|
+
title?: string
|
|
57
|
+
description?: string
|
|
58
|
+
multipleOf?: number
|
|
59
|
+
maximum?: number
|
|
60
|
+
exclusiveMaximum?: number | boolean
|
|
61
|
+
minimum?: number
|
|
62
|
+
exclusiveMinimum?: number | boolean
|
|
63
|
+
maxLength?: number
|
|
64
|
+
minLength?: number
|
|
65
|
+
pattern?: string | RegExp
|
|
66
|
+
additionalItems?: boolean | Schema
|
|
67
|
+
items?: Schema | Schema[]
|
|
68
|
+
maxItems?: number
|
|
69
|
+
minItems?: number
|
|
70
|
+
uniqueItems?: boolean
|
|
71
|
+
maxProperties?: number
|
|
72
|
+
minProperties?: number
|
|
73
|
+
required?: string[] | boolean
|
|
74
|
+
additionalProperties?: boolean | Schema
|
|
75
|
+
definitions?: {
|
|
76
|
+
[name: string]: Schema
|
|
77
|
+
}
|
|
78
|
+
properties?: {
|
|
79
|
+
[name: string]: Schema
|
|
80
|
+
}
|
|
81
|
+
patternProperties?: {
|
|
82
|
+
[name: string]: Schema
|
|
83
|
+
}
|
|
84
|
+
dependencies?: {
|
|
85
|
+
[name: string]: Schema | string[]
|
|
86
|
+
}
|
|
87
|
+
const?: any
|
|
88
|
+
'enum'?: any[]
|
|
89
|
+
type?: string | string[]
|
|
90
|
+
format?: string
|
|
91
|
+
allOf?: Schema[]
|
|
92
|
+
anyOf?: Schema[]
|
|
93
|
+
oneOf?: Schema[]
|
|
94
|
+
not?: Schema
|
|
95
|
+
if?: Schema
|
|
96
|
+
then?: Schema
|
|
97
|
+
else?: Schema
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface Options {
|
|
101
|
+
skipAttributes?: string[];
|
|
102
|
+
allowUnknownAttributes?: boolean;
|
|
103
|
+
preValidateProperty?: PreValidatePropertyFunction;
|
|
104
|
+
rewrite?: RewriteFunction;
|
|
105
|
+
base?: string;
|
|
106
|
+
throwError?: boolean;
|
|
107
|
+
required?: boolean;
|
|
108
|
+
throwFirst?: boolean;
|
|
109
|
+
throwAll?: boolean;
|
|
110
|
+
nestedErrors?: boolean;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface RewriteFunction {
|
|
114
|
+
(instance: any, schema: Schema, options: Options, ctx: SchemaContext): any;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface PreValidatePropertyFunction {
|
|
118
|
+
(instance: any, key: string, schema: Schema, options: Options, ctx: SchemaContext): any;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface SchemaContext {
|
|
122
|
+
schema: Schema;
|
|
123
|
+
options: Options;
|
|
124
|
+
propertyPath: string;
|
|
125
|
+
base: string;
|
|
126
|
+
schemas: {[base: string]: Schema};
|
|
127
|
+
makeChild: (schema: Schema, key: string) => SchemaContext;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface CustomFormat {
|
|
131
|
+
(input: any): boolean;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface CustomProperty {
|
|
135
|
+
(instance: any, schema: Schema, options: Options, ctx: SchemaContext): string|ValidatorResult;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface ErrorDetail {
|
|
139
|
+
message: string;
|
|
140
|
+
name: string;
|
|
141
|
+
argument: string;
|
|
142
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Validator = module.exports.Validator = require('./validator');
|
|
4
|
+
|
|
5
|
+
module.exports.ValidatorResult = require('./helpers').ValidatorResult;
|
|
6
|
+
module.exports.ValidatorResultError = require('./helpers').ValidatorResultError;
|
|
7
|
+
module.exports.ValidationError = require('./helpers').ValidationError;
|
|
8
|
+
module.exports.SchemaError = require('./helpers').SchemaError;
|
|
9
|
+
module.exports.SchemaScanResult = require('./scan').SchemaScanResult;
|
|
10
|
+
module.exports.scan = require('./scan').scan;
|
|
11
|
+
|
|
12
|
+
module.exports.validate = function (instance, schema, options) {
|
|
13
|
+
var v = new Validator();
|
|
14
|
+
return v.validate(instance, schema, options);
|
|
15
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var urilib = require('url');
|
|
4
|
+
var helpers = require('./helpers');
|
|
5
|
+
|
|
6
|
+
module.exports.SchemaScanResult = SchemaScanResult;
|
|
7
|
+
function SchemaScanResult(found, ref){
|
|
8
|
+
this.id = found;
|
|
9
|
+
this.ref = ref;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Adds a schema with a certain urn to the Validator instance.
|
|
14
|
+
* @param string uri
|
|
15
|
+
* @param object schema
|
|
16
|
+
* @return {Object}
|
|
17
|
+
*/
|
|
18
|
+
module.exports.scan = function scan(base, schema){
|
|
19
|
+
function scanSchema(baseuri, schema){
|
|
20
|
+
if(!schema || typeof schema!='object') return;
|
|
21
|
+
// Mark all referenced schemas so we can tell later which schemas are referred to, but never defined
|
|
22
|
+
if(schema.$ref){
|
|
23
|
+
var resolvedUri = urilib.resolve(baseuri, schema.$ref);
|
|
24
|
+
ref[resolvedUri] = ref[resolvedUri] ? ref[resolvedUri]+1 : 0;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
var id = schema.$id || schema.id;
|
|
28
|
+
var ourBase = id ? urilib.resolve(baseuri, id) : baseuri;
|
|
29
|
+
if (ourBase) {
|
|
30
|
+
// If there's no fragment, append an empty one
|
|
31
|
+
if(ourBase.indexOf('#')<0) ourBase += '#';
|
|
32
|
+
if(found[ourBase]){
|
|
33
|
+
if(!helpers.deepCompareStrict(found[ourBase], schema)){
|
|
34
|
+
throw new Error('Schema <'+ourBase+'> already exists with different definition');
|
|
35
|
+
}
|
|
36
|
+
return found[ourBase];
|
|
37
|
+
}
|
|
38
|
+
found[ourBase] = schema;
|
|
39
|
+
// strip trailing fragment
|
|
40
|
+
if(ourBase[ourBase.length-1]=='#'){
|
|
41
|
+
found[ourBase.substring(0, ourBase.length-1)] = schema;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
scanArray(ourBase+'/items', (Array.isArray(schema.items)?schema.items:[schema.items]));
|
|
45
|
+
scanArray(ourBase+'/extends', (Array.isArray(schema.extends)?schema.extends:[schema.extends]));
|
|
46
|
+
scanSchema(ourBase+'/additionalItems', schema.additionalItems);
|
|
47
|
+
scanObject(ourBase+'/properties', schema.properties);
|
|
48
|
+
scanSchema(ourBase+'/additionalProperties', schema.additionalProperties);
|
|
49
|
+
scanObject(ourBase+'/definitions', schema.definitions);
|
|
50
|
+
scanObject(ourBase+'/patternProperties', schema.patternProperties);
|
|
51
|
+
scanObject(ourBase+'/dependencies', schema.dependencies);
|
|
52
|
+
scanArray(ourBase+'/disallow', schema.disallow);
|
|
53
|
+
scanArray(ourBase+'/allOf', schema.allOf);
|
|
54
|
+
scanArray(ourBase+'/anyOf', schema.anyOf);
|
|
55
|
+
scanArray(ourBase+'/oneOf', schema.oneOf);
|
|
56
|
+
scanSchema(ourBase+'/not', schema.not);
|
|
57
|
+
}
|
|
58
|
+
function scanArray(baseuri, schemas){
|
|
59
|
+
if(!Array.isArray(schemas)) return;
|
|
60
|
+
for(var i=0; i<schemas.length; i++){
|
|
61
|
+
scanSchema(baseuri+'/'+i, schemas[i]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function scanObject(baseuri, schemas){
|
|
65
|
+
if(!schemas || typeof schemas!='object') return;
|
|
66
|
+
for(var p in schemas){
|
|
67
|
+
scanSchema(baseuri+'/'+p, schemas[p]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
var found = {};
|
|
72
|
+
var ref = {};
|
|
73
|
+
scanSchema(base, schema);
|
|
74
|
+
return new SchemaScanResult(found, ref);
|
|
75
|
+
};
|