daily pastebin goal
16%
SHARE
TWEET

Untitled

a guest Jul 12th, 2018 52 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const
  2.     /*
  3.         Node Internals
  4.     */
  5.     UTIL        = require('util'),
  6.  
  7.     /*
  8.         Npm Third Party
  9.     */
  10.     _           = require('lodash'),
  11.  
  12.     /*
  13.         Global Variables
  14.     */
  15.     TYPE_MAP    = {
  16.                     string          : 'string',
  17.                     number          : 'number',
  18.                     boolean         : 'boolean',
  19.                     array           : 'array',
  20.                     object          : 'object'
  21.                 },
  22.     PRIM_ARRAY  = [
  23.                     'string',
  24.                     'number',
  25.                     'boolean'
  26.                 ];
  27.  
  28. class jsonValidator {
  29.  
  30.     validate(schema, jsonData) {
  31.  
  32.         if(typeof jsonData !== TYPE_MAP.object)
  33.             return "input not a valid json";
  34.  
  35.         try{
  36.             checkLevelKeys(schema.properties, jsonData);
  37.         } catch (errorMessage) {
  38.             return errorMessage.message;
  39.         }
  40.  
  41.         return true;
  42.     }
  43.  
  44.     isValidJsonSchema(schema) {
  45.         if(!schema.properties || !UTIL.isArray(schema.properties))
  46.             throw new Error('Not a valid schema!');
  47.  
  48.         const
  49.             mandatorySchemaPropertyKeys = [
  50.                                             'keyName',
  51.                                             'keyType'
  52.                                         ];
  53.         try{
  54.             schema.properties.forEach( (property) => {
  55.  
  56.                 mandatorySchemaPropertyKeys.forEach( (propertyKey) => {
  57.                     if(!_.get(property, propertyKey, null))
  58.                         throw new Error(`${propertyKey} missing`);
  59.                 });
  60.  
  61.                 if(property.properties)
  62.                     return isValidJsonSchema(property);
  63.             });
  64.         } catch (error){  
  65.             return false;
  66.         }
  67.  
  68.         return true;
  69.     }
  70. }
  71.  
  72. /*
  73.     Util unexposed functions
  74. */
  75.  
  76. function checkLevelKeys(properties, jsonData, keyParentLocationArray=[]) {
  77.     if(UTIL.isArray(jsonData)){
  78.         jsonData.forEach( (dataAtom, index) => {
  79.             properties.forEach( (property) => {
  80.                 const
  81.                     keyName             = _.get(property,       'keyName',        ''),
  82.                     keyType             = _.get(property,       'keyType',        ''),
  83.                     isMandatory         = _.get(property,       'isMandatory',    false),
  84.                     valueReceived       = _.get(dataAtom,       keyName,          null),
  85.                     keyLocationArray    = _.cloneDeep(keyParentLocationArray);
  86.  
  87.                 keyLocationArray.push(index);
  88.                 keyLocationArray.push(keyName);
  89.  
  90.  
  91.                 if(valueReceived || valueReceived === false)
  92.                     validateType(property, keyType, valueReceived, keyLocationArray);
  93.                 else if(isMandatory)
  94.                     throw new Error(`${keyLocationArrayStringCreator(keyLocationArray)} is missing`);
  95.             });
  96.         });
  97.     } else{
  98.         properties.forEach( (property) => {
  99.             const
  100.                 keyName             = _.get(property,       'keyName',        ''),
  101.                 keyType             = _.get(property,       'keyType',        ''),
  102.                 isMandatory         = _.get(property,       'isMandatory',    false),
  103.                 valueReceived       = _.get(jsonData,       keyName,          null),
  104.                 keyLocationArray    = _.cloneDeep(keyParentLocationArray);
  105.  
  106.             keyLocationArray.push(keyName);
  107.  
  108.  
  109.             if(valueReceived || valueReceived === false)
  110.                 validateType(property, keyType, valueReceived, keyLocationArray);
  111.             else if(isMandatory)
  112.                 throw new Error(`${keyLocationArrayStringCreator(keyLocationArray)} is missing`);
  113.         });
  114.     }
  115. }
  116.  
  117. function validateType(property, keyType, valueReceived, keyLocationArray){
  118.     /*
  119.         In case there is an error
  120.         we are already prepared
  121.     */
  122.     const
  123.         errorMessage = makeTypeErrorString(keyLocationArray, keyType),
  124.         errorKeyType = makeTypeErrorString(keyType);
  125.  
  126.     switch(keyType){
  127.  
  128.         case TYPE_MAP.string :
  129.  
  130.             if(typeof valueReceived !== TYPE_MAP.string)
  131.                 throw new Error(errorMessage);
  132.  
  133.             break;
  134.  
  135.         case TYPE_MAP.number :
  136.  
  137.             if(typeof valueReceived !== TYPE_MAP.number)
  138.                 throw new Error(errorMessage);
  139.  
  140.             break;
  141.  
  142.         case TYPE_MAP.boolean :
  143.  
  144.             if(typeof valueReceived !== TYPE_MAP.boolean)
  145.                 throw new Error(errorMessage);
  146.  
  147.             break;
  148.  
  149.         case TYPE_MAP.array :
  150.  
  151.             if(!UTIL.isArray(valueReceived))
  152.                 throw new Error(errorMessage);
  153.             if (property.type)
  154.                 checkValuesInAnArray(property.type, valueReceived, keyLocationArray);
  155.             else if(property.properties)
  156.                 checkLevelKeys(property.properties, valueReceived, keyLocationArray, true);
  157.  
  158.             break;
  159.  
  160.         case TYPE_MAP.object :
  161.  
  162.             if( (typeof valueReceived !== TYPE_MAP.object) || (UTIL.isArray(valueReceived)) )
  163.                 throw new Error(errorMessage);
  164.  
  165.             if(property.properties)
  166.                 checkLevelKeys(property.properties, valueReceived, keyLocationArray);
  167.  
  168.             break;
  169.  
  170.         default :
  171.  
  172.             throw new Error(errorKeyType);
  173.     }
  174. }
  175.  
  176. function makeTypeErrorString(keyLocationArray, expectedKeyType){
  177.     if(expectedKeyType)
  178.         return `${keyLocationArrayStringCreator(keyLocationArray)} was expected to be a ${expectedKeyType}`;
  179.     else
  180.         expectedKeyType = keyLocationArray
  181.         return `${expectedKeyType} not supported in validator`;
  182. }
  183.  
  184. function keyLocationArrayStringCreator(keyLocationArray){
  185.     return keyLocationArray.join('.');
  186. }
  187.  
  188. function checkValuesInAnArray(type, data, keyLocationArray){
  189.  
  190.     if(!PRIM_ARRAY.includes(type))
  191.         throw new Error (`${type} not supported for primitive arrays`);
  192.  
  193.     data.forEach( (dataAtom, index) => {
  194.         if(typeof dataAtom !== type){
  195.             keyLocationArray.push(index);
  196.             throw new Error (makeTypeErrorString(keyLocationArray, type));
  197.         }
  198.     });
  199. }
  200.  
  201. module.exports = jsonValidator;
  202.  
  203.  
  204. (() => {
  205.     const
  206.         mySchema  = {
  207.                         properties              : [{
  208.                             keyName             : 'name',
  209.                             keyType             : 'string',
  210.                             isMandatory         : true
  211.                         },{
  212.                             keyName             : 'someBool',
  213.                             keyType             : 'boolean',
  214.                             isMandatory         : true
  215.                         },{
  216.                             keyName             : 'age',
  217.                             keyType             : 'number',
  218.                             isMandatory         : true
  219.                         },{
  220.                             keyName             : 'day',
  221.                             keyType             : 'string',
  222.                             isMandatory         : false
  223.                         },{
  224.                             keyName             : 'sArray',
  225.                             keyType             : 'array',
  226.                             isMandatory         : true,
  227.                             type                : 'boolean',
  228.                         },{
  229.                             keyName             : 'a',
  230.                             keyType             : 'array',
  231.                             isMandatory         : true,
  232.                             properties          : [{
  233.                                 keyName         : 'name',
  234.                                 keyType         : 'string',
  235.                                 isMandatory     : true
  236.                             },{
  237.                                 keyName         : 'age',
  238.                                 keyType         : 'number',
  239.                                 isMandatory     : true
  240.                             },{
  241.                                 keyName         : 'dummy',
  242.                                 keyType         : 'array',
  243.                                 isMandatory     : true,
  244.                                 properties      : [{
  245.                                     keyName     : 'r',
  246.                                     keyType     : 'string',
  247.                                     isMandatory : true
  248.                                 }]
  249.                             }]
  250.                         },{
  251.                             keyName             : 'ab',
  252.                             keyType             : 'object',
  253.                             isMandatory         : true,
  254.                             properties          : [{
  255.                                 keyName         : 'name',
  256.                                 keyType         : 'string',
  257.                                 isMandatory     : true
  258.                             },{
  259.                                 keyName         : 'age',
  260.                                 keyType         : 'number',
  261.                                 isMandatory     : true
  262.                             }]
  263.                         }]
  264.                     },
  265.         myTestJson  = {
  266.                         name        : 'Vidur Khanna',
  267.                         someBool    : false,
  268.                         age         : 23,
  269.                         sArray      : [true, false],
  270.                         a           : [{
  271.                                         name    : 'dasdas',
  272.                                         age     : 23,
  273.                                         dummy   : [{
  274.                                             r   : 'sdagdjafsd'
  275.                                         }]
  276.                                     }],
  277.                         ab          : {
  278.                                         name    : 'Vidur Khanna',
  279.                                         age     : 23,
  280.                                     }
  281.                     },
  282.         jV          = new jsonValidator();
  283.  
  284.     console.log('isJsonValid -> ', jV.validate(mySchema, myTestJson));
  285. })();
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top