]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/jsprim/node_modules/json-schema/lib/validate.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / request / node_modules / http-signature / node_modules / jsprim / node_modules / json-schema / lib / validate.js
1 /**
2  * JSONSchema Validator - Validates JavaScript objects using JSON Schemas
3  *      (http://www.json.com/json-schema-proposal/)
4  *
5  * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com)
6  * Licensed under the MIT (MIT-LICENSE.txt) license.
7 To use the validator call the validate function with an instance object and an optional schema object.
8 If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
9 that schema will be used to validate and the schema parameter is not necessary (if both exist,
10 both validations will occur).
11 The validate method will return an array of validation errors. If there are no errors, then an
12 empty list will be returned. A validation error will have two properties:
13 "property" which indicates which property had the error
14 "message" which indicates what the error was
15  */
16 ({define:typeof define!="undefined"?define:function(deps, factory){module.exports = factory();}}).
17 define([], function(){
18 var exports = validate;
19 // setup primitive classes to be JSON Schema types
20 exports.Integer = {type:"integer"};
21 var primitiveConstructors = {
22         String: String,
23         Boolean: Boolean,
24         Number: Number,
25         Object: Object,
26         Array: Array,
27         Date: Date
28 }
29 exports.validate = validate;
30 function validate(/*Any*/instance,/*Object*/schema) {
31                 // Summary:
32                 //      To use the validator call JSONSchema.validate with an instance object and an optional schema object.
33                 //              If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
34                 //              that schema will be used to validate and the schema parameter is not necessary (if both exist,
35                 //              both validations will occur).
36                 //              The validate method will return an object with two properties:
37                 //                      valid: A boolean indicating if the instance is valid by the schema
38                 //                      errors: An array of validation errors. If there are no errors, then an
39                 //                                      empty list will be returned. A validation error will have two properties:
40                 //                                              property: which indicates which property had the error
41                 //                                              message: which indicates what the error was
42                 //
43                 return validate(instance, schema, {changing: false});//, coerce: false, existingOnly: false});
44         };
45 exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/property) {
46                 // Summary:
47                 //              The checkPropertyChange method will check to see if an value can legally be in property with the given schema
48                 //              This is slightly different than the validate method in that it will fail if the schema is readonly and it will
49                 //              not check for self-validation, it is assumed that the passed in value is already internally valid.
50                 //              The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
51                 //              information.
52                 //
53                 return validate(value, schema, {changing: property || "property"});
54         };
55 var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Object*/options) {
56
57         if (!options) options = {};
58         var _changing = options.changing;
59
60         function getType(schema){
61                 return schema.type || (primitiveConstructors[schema.name] == schema && schema.name.toLowerCase());
62         }
63         var errors = [];
64         // validate a value against a property definition
65         function checkProp(value, schema, path,i){
66
67                 var l;
68                 path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i;
69                 function addError(message){
70                         errors.push({property:path,message:message});
71                 }
72
73                 if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && getType(schema))){
74                         if(typeof schema == 'function'){
75                                 if(!(value instanceof schema)){
76                                         addError("is not an instance of the class/constructor " + schema.name);
77                                 }
78                         }else if(schema){
79                                 addError("Invalid schema/property definition " + schema);
80                         }
81                         return null;
82                 }
83                 if(_changing && schema.readonly){
84                         addError("is a readonly field, it can not be changed");
85                 }
86                 if(schema['extends']){ // if it extends another schema, it must pass that schema as well
87                         checkProp(value,schema['extends'],path,i);
88                 }
89                 // validate a value against a type definition
90                 function checkType(type,value){
91                         if(type){
92                                 if(typeof type == 'string' && type != 'any' &&
93                                                 (type == 'null' ? value !== null : typeof value != type) &&
94                                                 !(value instanceof Array && type == 'array') &&
95                                                 !(value instanceof Date && type == 'date') &&
96                                                 !(type == 'integer' && value%1===0)){
97                                         return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}];
98                                 }
99                                 if(type instanceof Array){
100                                         var unionErrors=[];
101                                         for(var j = 0; j < type.length; j++){ // a union type
102                                                 if(!(unionErrors=checkType(type[j],value)).length){
103                                                         break;
104                                                 }
105                                         }
106                                         if(unionErrors.length){
107                                                 return unionErrors;
108                                         }
109                                 }else if(typeof type == 'object'){
110                                         var priorErrors = errors;
111                                         errors = [];
112                                         checkProp(value,type,path);
113                                         var theseErrors = errors;
114                                         errors = priorErrors;
115                                         return theseErrors;
116                                 }
117                         }
118                         return [];
119                 }
120                 if(value === undefined){
121                         if(schema.required){
122                                 addError("is missing and it is required");
123                         }
124                 }else{
125                         errors = errors.concat(checkType(getType(schema),value));
126                         if(schema.disallow && !checkType(schema.disallow,value).length){
127                                 addError(" disallowed value was matched");
128                         }
129                         if(value !== null){
130                                 if(value instanceof Array){
131                                         if(schema.items){
132                                                 var itemsIsArray = schema.items instanceof Array;
133                                                 var propDef = schema.items;
134                                                 for (i = 0, l = value.length; i < l; i += 1) {
135                                                         if (itemsIsArray)
136                                                                 propDef = schema.items[i];
137                                                         if (options.coerce)
138                                                                 value[i] = options.coerce(value[i], propDef);
139                                                         errors.concat(checkProp(value[i],propDef,path,i));
140                                                 }
141                                         }
142                                         if(schema.minItems && value.length < schema.minItems){
143                                                 addError("There must be a minimum of " + schema.minItems + " in the array");
144                                         }
145                                         if(schema.maxItems && value.length > schema.maxItems){
146                                                 addError("There must be a maximum of " + schema.maxItems + " in the array");
147                                         }
148                                 }else if(schema.properties || schema.additionalProperties){
149                                         errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties));
150                                 }
151                                 if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){
152                                         addError("does not match the regex pattern " + schema.pattern);
153                                 }
154                                 if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){
155                                         addError("may only be " + schema.maxLength + " characters long");
156                                 }
157                                 if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){
158                                         addError("must be at least " + schema.minLength + " characters long");
159                                 }
160                                 if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum &&
161                                                 schema.minimum > value){
162                                         addError("must have a minimum value of " + schema.minimum);
163                                 }
164                                 if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum &&
165                                                 schema.maximum < value){
166                                         addError("must have a maximum value of " + schema.maximum);
167                                 }
168                                 if(schema['enum']){
169                                         var enumer = schema['enum'];
170                                         l = enumer.length;
171                                         var found;
172                                         for(var j = 0; j < l; j++){
173                                                 if(enumer[j]===value){
174                                                         found=1;
175                                                         break;
176                                                 }
177                                         }
178                                         if(!found){
179                                                 addError("does not have a value in the enumeration " + enumer.join(", "));
180                                         }
181                                 }
182                                 if(typeof schema.maxDecimal == 'number' &&
183                                         (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){
184                                         addError("may only have " + schema.maxDecimal + " digits of decimal places");
185                                 }
186                         }
187                 }
188                 return null;
189         }
190         // validate an object against a schema
191         function checkObj(instance,objTypeDef,path,additionalProp){
192
193                 if(typeof objTypeDef =='object'){
194                         if(typeof instance != 'object' || instance instanceof Array){
195                                 errors.push({property:path,message:"an object is required"});
196                         }
197
198                         for(var i in objTypeDef){
199                                 if(objTypeDef.hasOwnProperty(i)){
200                                         var value = instance[i];
201                                         // skip _not_ specified properties
202                                         if (value === undefined && options.existingOnly) continue;
203                                         var propDef = objTypeDef[i];
204                                         // set default
205                                         if(value === undefined && propDef["default"]){
206                                                 value = instance[i] = propDef["default"];
207                                         }
208                                         if(options.coerce && i in instance){
209                                                 value = instance[i] = options.coerce(value, propDef);
210                                         }
211                                         checkProp(value,propDef,path,i);
212                                 }
213                         }
214                 }
215                 for(i in instance){
216                         if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){
217                                 if (options.filter) {
218                                         delete instance[i];
219                                         continue;
220                                 } else {
221                                         errors.push({property:path,message:(typeof value) + "The property " + i +
222                                                 " is not defined in the schema and the schema does not allow additional properties"});
223                                 }
224                         }
225                         var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires;
226                         if(requires && !(requires in instance)){
227                                 errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"});
228                         }
229                         value = instance[i];
230                         if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){
231                                 if(options.coerce){
232                                         value = instance[i] = options.coerce(value, additionalProp);
233                                 }
234                                 checkProp(value,additionalProp,path,i);
235                         }
236                         if(!_changing && value && value.$schema){
237                                 errors = errors.concat(checkProp(value,value.$schema,path,i));
238                         }
239                 }
240                 return errors;
241         }
242         if(schema){
243                 checkProp(instance,schema,'',_changing || '');
244         }
245         if(!_changing && instance && instance.$schema){
246                 checkProp(instance,instance.$schema,'','');
247         }
248         return {valid:!errors.length,errors:errors};
249 };
250 exports.mustBeValid = function(result){
251         //      summary:
252         //              This checks to ensure that the result is valid and will throw an appropriate error message if it is not
253         // result: the result returned from checkPropertyChange or validate
254         if(!result.valid){
255                 throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n"));
256         }
257 }
258
259 return exports;
260 });