lib/validators/type.js
function type(cmd, args, info) {
  // definition provided by earlier command validation
  /* istanbul ignore next: currently subcommands do not type validate */
  var def = info.command.sub ? info.command.sub.def : info.command.def
    // expected type of the value based on the supplied command
    , expected = TYPES[cmd]
    , numeric = NUMERIC[cmd]
    , margs = args.slice(0)
    // extract keys from the args list
    , keys = def.getKeys(args)
    // build up value list, when validation
    // passes this can be re-used by calling code
    , values = {}
    , i, k, v, nv;

  // numeric argument validation
  if(numeric && numeric.pos) {
    numeric.pos.forEach(function(pos) {
      //console.error('got value for arg at pos %s (%s)', pos, args[pos]);
      var val = num(numeric.type, args[pos]);
      margs[pos] = val;
      args[pos] = val;
    })
  }

  // command does not operate on a type or has no keys
  // nothing to be done. first part of the conditional
  // should never match, if it does it represents a misconfiguration
  // of the constants, however we need to ensure we have some keys
  // to iterate over
  if(!keys || !TYPES[cmd]) return null;

  for(i = 0;i < keys.length;i++) {
    k = keys[i];
    v = nv = info.db.getKey(k, {});

    //console.dir(v);

    // numeric value validation
    if(numeric) {

      if(expected === TYPE_NAMES.STRING && numeric.value) {
        // update the value, allows
        // calling code to skip coercion
        // on successful validation
        v = num(numeric.type, v);
      // should have a hash
      // need to dig deeper to get the real
      // value for complex types
      }else if(v && expected === TYPE_NAMES.HASH && numeric.value) {
        nv = v.getValues(cmd, args, def);
        //console.error('got validate value: %s', nv);
        num(numeric.type, nv);
      }
    }

    // got an existing value
    if(v !== undefined) {

      //console.dir(v);

      switch(expected) {
        case TYPE_NAMES.STRING:

          // the store is allowed to save string values as
          // numbers and coerce to strings on get()
          if(typeof v !== 'string'
            && typeof v !== 'number'
            && !(v instanceof Buffer)) {
            throw WrongType;
          }
          break;
        case TYPE_NAMES.HASH:
        case TYPE_NAMES.LIST:
        case TYPE_NAMES.SET:
        case TYPE_NAMES.ZSET:
          if(v.rtype !== expected) throw WrongType;
          break;
      }
    }

    // always store regardless of whether a value is defined
    values[k] = v;
  }

  return {keys: keys, values: values, args: margs};
}
function type(cmd, args, info) {
  // definition provided by earlier command validation
  /* istanbul ignore next: currently subcommands do not type validate */
  var def = info.command.sub ? info.command.sub.def : info.command.def
    // expected type of the value based on the supplied command
    , expected = TYPES[cmd]
    , numeric = NUMERIC[cmd]
    , margs = args.slice(0)
    // extract keys from the args list
    , keys = def.getKeys(args)
    // build up value list, when validation
    // passes this can be re-used by calling code
    , values = {}
    , i, k, v, nv;

  // numeric argument validation
  if(numeric && numeric.pos) {
    numeric.pos.forEach(function(pos) {
      //console.error('got value for arg at pos %s (%s)', pos, args[pos]);
      var val = num(numeric.type, args[pos]);
      margs[pos] = val;
      args[pos] = val;
    })
  }

  // command does not operate on a type or has no keys
  // nothing to be done. first part of the conditional
  // should never match, if it does it represents a misconfiguration
  // of the constants, however we need to ensure we have some keys
  // to iterate over
  if(!keys || !TYPES[cmd]) return null;

  for(i = 0;i < keys.length;i++) {
    k = keys[i];
    v = nv = info.db.getKey(k, {});

    //console.dir(v);

    // numeric value validation
    if(numeric) {

      if(expected === TYPE_NAMES.STRING && numeric.value) {
        // update the value, allows
        // calling code to skip coercion
        // on successful validation
        v = num(numeric.type, v);
      // should have a hash
      // need to dig deeper to get the real
      // value for complex types
      }else if(v && expected === TYPE_NAMES.HASH && numeric.value) {
        nv = v.getValues(cmd, args, def);
        //console.error('got validate value: %s', nv);
        num(numeric.type, nv);
      }
    }

    // got an existing value
    if(v !== undefined) {

      //console.dir(v);

      switch(expected) {
        case TYPE_NAMES.STRING:

          // the store is allowed to save string values as
          // numbers and coerce to strings on get()
          if(typeof v !== 'string'
            && typeof v !== 'number'
            && !(v instanceof Buffer)) {
            throw WrongType;
          }
          break;
        case TYPE_NAMES.HASH:
        case TYPE_NAMES.LIST:
        case TYPE_NAMES.SET:
        case TYPE_NAMES.ZSET:
          if(v.rtype !== expected) throw WrongType;
          break;
      }
    }

    // always store regardless of whether a value is defined
    values[k] = v;
  }

  return {keys: keys, values: values, args: margs};
}
function type ( cmd , args , info ) { // definition provided by earlier command validation /* istanbul ignore next: currently subcommands do not type validate */ var def = info . command . sub ? info . command . sub . def : info . command . def // expected type of the value based on the supplied command , expected = TYPES [ cmd ] , numeric = NUMERIC [ cmd ] , margs = args . slice ( 0 ) // extract keys from the args list , keys = def . getKeys ( args ) // build up value list, when validation // passes this can be re-used by calling code , values = { } , i , k , v , nv ; // numeric argument validation if ( numeric && numeric . pos ) { numeric . pos . forEach ( function ( pos ) { //console.error('got value for arg at pos %s (%s)', pos, args[pos]); var val = num ( numeric . type , args [ pos ] ) ; margs [ pos ] = val ; args [ pos ] = val ; } ) } // command does not operate on a type or has no keys // nothing to be done. first part of the conditional // should never match, if it does it represents a misconfiguration // of the constants, however we need to ensure we have some keys // to iterate over if ( ! keys || ! TYPES [ cmd ] ) return null ; for ( i = 0 ; i < keys . length ; i ++ ) { k = keys [ i ] ; v = nv = info . db . getKey ( k , { } ) ; //console.dir(v); // numeric value validation if ( numeric ) { if ( expected === TYPE_NAMES . STRING && numeric . value ) { // update the value, allows // calling code to skip coercion // on successful validation v = num ( numeric . type , v ) ; // should have a hash // need to dig deeper to get the real // value for complex types } else if ( v && expected === TYPE_NAMES . HASH && numeric . value ) { nv = v . getValues ( cmd , args , def ) ; //console.error('got validate value: %s', nv); num ( numeric . type , nv ) ; } } // got an existing value if ( v !== undefined ) { //console.dir(v); switch ( expected ) { case TYPE_NAMES . STRING : // the store is allowed to save string values as // numbers and coerce to strings on get() if ( typeof v !== 'string' && typeof v !== 'number' && ! ( v instanceof Buffer ) ) { throw WrongType ; } break ; case TYPE_NAMES . HASH : case TYPE_NAMES . LIST : case TYPE_NAMES . SET : case TYPE_NAMES . ZSET : if ( v . rtype !== expected ) throw WrongType ; break ; } } // always store regardless of whether a value is defined values [ k ] = v ; } return { keys : keys , values : values , args : margs } ; }
Validate whether a command is operating on the correct type.

@param cmd The command name (lowercase).
@param args The command arguments, must be an array.
@param info The server information.
Validate whether a command is operating on the correct type .