abstract-type

0.4.4 • Public • Published

abstract-type npm

Build Status Code Climate Test Coverage downloads license

The abstract-type library includes the abstract Type class and Value class for streamable type info and validating value.

Concepts

  • Primitive Types
    • All registered types are primitive types.
    • It's the singleton type object on the global type factory.
  • Virtual Types
    • It's an object of a primitive type.
    • It can not be registered to the global type factory.
    • It could be unlimited number of virtual types.
      • It could use the LRU-cache factory to cache these virtual types(see usage).
  • Type Attributes: the attributes of the type. It's used to constrain the Type. All types have the name and required attributes.
    • name (string): the type name.
      • required = true: the type name must be required.
      • enumerable = false: the type name can not be enumerable.
    • required (boolean): the attribute whether is required(must be exists, not optional). default to false.
  • Value: the value with corresponding to the type information.

Usage

Create the number type

The type has a name and can verify whether a value belongs to that type. We can draw the two concepts related to the type, from here:

  • Attributes: the attributes(meta data) of this type.

  • Value: the value of this type.

  • The Type Class

    • Properties:
      • $attributes (object): the attributes of this type.
    • Methods(should be overridden):
      • _initialize(aOptions): initialize the type object.
      • _assign(options): assign an options of type to itself.
      • _validate(aValue, aOptions): validate a value whether is valid.
      • valueToString(aValue): (optional) convert the value to string, it's used to convert to json.
      • toValue(aString): (optional) convert the string to the value, it's used to convert from json and assign from value.
      • ValueType property: (optional) defaults to Value Class. unless implement your own Value class.
  • The Value Class

    • Properties:
      • value: store the value here.
      • $type (Type): point to the type of this value.
    • Static/Class Methods:
      • tryGetTypeName(Value): try to guess the type name of the value.
      • constructor(value[, type[, options]]): create a value instance.
        • value: the assigned value. it will guess the type of the value if no type provided.
        • type (Type): the type of the value
        • options (object): the optional type of value options. it will create a new type if exists.
    • Methods:
      • clone(): clone this value object.
      • assign(value, options): assign the value.
        • aOptions (object):
          • checkValidity (boolean): defaults to true.
      • fromJson(json): assign a value from json string.
      • createFromJson(json): create a new value object from json string.
      • isValid(): whether the value is valid.
      • toObject(aOptions): return a parametric object of the value. it wont include type info. unless set the withType is true.
        • aOptions (object):
          • withType (boolean): whether includes the type info. default to false
    • These methods could be overridden:
      • _toObject(aOptions): return the parametric object of this value.
      • valueOf(): return the value.
      • _assign(value): assign the value to itself.
  • The Attributes class: describe the attributes of a type. an attribute could include these properties:

    • name (string): the attribute name. you can specify a non-english name.
      • the english name(the attributes' key) is used in the internal of the type.
      • the name only used on export(toObject) or import(assign).
    • type (string): the attribute type.
    • enumerable (boolean): the attribute whether is a hidden attribute, defaults to true.
      • the hidden attribute can not export to the parametric object(serialized).
      • note: It's a hidden attribute too if attribute name begins with '$' char.
    • required (boolean): the attribute whether it's required(MUST HAVE).
    • value: the default value of the attribute.
    • assign(value, dest, src, key) (function): optional special function to assign the attribute's value from src[key] to dest[key].
      • src, dest: the type object or the parametric type object.
TypeAttributes    = require 'abstract-type/lib/attributes'
Type              = require 'abstract-type'
register          = Type.register
aliases           = Type.aliases
 
class NumberType
  register NumberType
  aliases NumberType'number'
 
  $attributes: TypeAttributes
    min:
      name: 'min'
      type: 'Number'
    max:
      name: 'max'
      type: 'Number'
 
  #valueToString: (aValue)-> 
  #  aValue = String(aValue) 
  stringToValue: (aString)->
    if isInt aString
      aString = parseInt(aString)
    else if isFloat aString
      aString = parseFloat(aString)
    else
      aString = undefined
    aString
  _validate: (aValue, aOptions)->
    aValue = @stringToValue(aValue) if isString aValue
    result = isNumber aValue
    if result
      if aOptions
        vMin = aOptions.min
        vMax = aOptions.max
        if vMin?
          result = aValue >= vMin
          if not result
            @error "should be equal or greater than minimum value: " + vMin
        if result and vMax?
          result = aValue <= vMax
          if not result
            @error "should be equal or less than maximum value: " + vMax
    result

Use the number type

  • Type(aTypeName, aOptions)
    • get the type info object from glabal cache if aOptions is null or the same as the original/default attributes value.
    • else create a new virtual type info object.
  • type.createType(aObject) (Type::createType)
    • create a new type info object instance always.
    • the aObject.name should be exists as the type name.
var cacheable = require('cache-factory')
var Type      = cacheable(require('abstract-type')) // apply the cache-able ability to Type
require('number-type') //register the number type to Type.
 
var number = Type('Number') // get the number type object.
assert.equal(number, Type('Number'))
 
var num = Type('Number', {min:1, max:6}) // create non-name a virutal type object.
assert.notEqual(number, num)
 
var NumberType = Type.registeredClass('Number') // get Number Type Class
 
// create a virtual type object
var TPositiveNumber = Type('Number', {min:0, cached: 'PositiveNumber'})
 
 
assert.notOk(TPositiveNumber.isValid(-1))
assert.ok(TPositiveNumber.isValid(1)) // validate a value
 
var n = TPositiveNumber.create(123) // create the value
= TPositiveNumber.createValue(123)
assert.ok(n.isValid())
assert.equal(Number(n) + 3, 126)
 
//get the virtual type from cache:
var N = Type('/type/AbstractNumber/Number/PositiveNumber')
//N = NumberType('PositiveNumber')
assert.equals(N, TPositiveNumber);
 

API

Type = require('abstract-type')

It's the abstract type info class and the type info manager.

  • constructor([typeName, ]options): get a the default type info instance object from global cache or create a new virutal type object.
    • arguments

      • typeName (string): the type name.
      • options (object): optional type options to apply. different types have different options.
        • name (string): the type name.
        • validate (function): assign the custom validate function.
          • function(value) the first argument is the value to validate.
            • return the validation result.
          • stored into the customValidate property internal.
        • ...: the type's specified options to create a new virtual type object.
    • return

      • (object): the type object instance.
    • eg:

      // get the default type object
      var TNumber = Type('number')
      // other way to get the default type object
      TNumber = Type({name: 'number'})
      // another way to get the default type object
      TNumber = NumberType()
      // create a new virtual type object.
      var TPositiveNumber = Type('number', {min:0})
      assert.notEqual(TPositiveNumber, TNumber)
       
      // create a new virtual type object.
      TPositiveNumber = Type('number', {validate: function(v){return v>=0}})
      assert.notEqual(TPositiveNumber, TNumber)
  • Type.create(typeName, options):This class method is used to create a new Type instance object.
    • arguments
      • typeName (string): the type name.
      • options (object): optional type options. different types have different options.
    • return
      • (object): the created type object instance.
  • Type.createFrom(aObject): the class method to create a type object or value object from a parametric type object.
    • arguments
      • aObject (object): the encoding string should be decoded to an object.
        • name (string): the type name required.
        • value : the optional value. return value object if exists.
    • return
      • (object):
        • the created type object instance with the type info if no value in it.
        • the created value object instance if value in it.
  • Type.createFromJson(json):the class method to create a type object or value object from a json string.
    • arguments
      • json (string): the json string with type info.
        • name (string): the type name required.
        • value : the optional value. return value object if exists.
    • return
      • (object):
        • the created type object instance with the type info if no value in it.
        • the created value object instance if value in it.
  • Type.registerValidator(aValidator):This class method is used to register a custom validator.
    • arguments
      • aValidator (object): the validator.
        • name (string): the validator option name.
        • validate (function): the validator function: function(value, options)
    • return
      • (boolean): whether successful.
  • Type.registerValidator(name, validate):This class method is used to register a custom validator.
    • arguments
      • name (string): the validator option name.
      • validate (function): the validator function: function(value, options)
    • return
      • (boolean): whether successful.
  • Type.unregisterValidator(name):This class method is used to unregister a custom validator.
    • arguments
      • name (string): the validator name to unregister.
    • return
      • (boolean): whether successful.
  • cloneType():the instance method to clone the type object itself.
    • alias: clone

    • return

      • (object): the created type object instance with same type info.
    • eg:

      var num = Type('Number', min:1)
      var num1 = num.cloneType()
      assert.ok(num.isSame(num1))
  • createType(options): create a new the type object of this type with the type options.
    • arguments
      • options (object): optional type options. different types have different options.
        • it is the same as cloneType() if no options
    • return
      • (object): the created type object instance with the type info options.
  • createValue(value, options):create a value from the type.
    • alias: create
    • arguments
      • value (Type): the value of this type to create
      • options (object): optional type options
        • the new virtual type of the value will be created if exists
    • return
      • (object): the created value object instance.
  • toObject(aObject, aNameRequired = true):convert the type info into aObject(an parametric type object). It could be streamable your type.
    • arguments
      • options (object): optional options
        • value (Type): optional value, when value exists, the following options used:
        • typeOnly (boolean): just type info if true. defaults to false.
      • aNameRequired (boolean): write the name to aObject. defaults to true.
    • return
      • (object): the created object with type info.
  • toJson(options):convert the type info to a json string. It could be streamable your type. It is almost equivalent to JSON.stringify(theTypeObject).
    • arguments
      • options (object): optional options
        • value (Type): optional value, when value exists, the following options used:
        • typeOnly (boolean): just type info if true. defaults to false.
    • return
      • (string): the json string with type info.
  • validate(value, raiseError, options):validate a specified value whether is valid.
    • arguments
      • value (Type): the value to validate
      • raiseError (boolean): whether throw error if validate failed. defaults to true.
      • options (object): optional type options to override. defaults to this type options.
    • return
      • (boolean): whether is valid if no raise error.

Value = require('abstract-type').Value

the value class.

You should implement the valueToString(aValue) and stringToValue(aString) method in your derived type class to make the value streamable.

  • constructor(value[[, type], options]): create a value object.
    • arguments
      • value (Type): the value to be created.
        • it will guess the type if no type object.
      • type (Object): the optional type object.
      • options (object): optional type options.
        • checkValidity (boolean): whether check the value is valid. defaults to true.
    • return
      • (object): the created value object instance.
  • property $type: point to a type object. It can not be enumerable.
  • clone(): clone the value object.
    • return
      • (object): the created new value object instance with same as original info.
  • create(value, options):create a new the value object.
    • arguments
      • value (Type): the value to be created. MUST BE the same type.
      • options (object): optional type options.
        • checkValidity (boolean): whether check the value is valid. defaults to true.
    • return
      • (object): the created value object instance.
  • assign(value, options):assign a value to itself.
    • arguments
      • value (Type): the value to be assigned. MUST BE the same type.
      • options (object): optional type options.
        • checkValidity (boolean): whether check the value is valid. defaults to true.
    • return
      • (object): this object.
  • isValid(): validate the value whether is valid.
    • return
      • (boolean): whether the value is valid.
  • toObject(options):convert the value to an object. It wont include type info via defaults. It could be streamable your value.
    • arguments

      • options (object): optional options
        • withType (Boolean): whether with type info, defaults to false.
    • return

      • (object): the value and type info(if withType).
    • eg:

      var Type  = require('abstract-type')
      var Value = Type.Value
       
      var val = Value(1, Type 'Number')
       
      assert.equal val.toObject(), 1
       

TODO

  • compare(value1, value2) and equals(value1, value2) to compare value.

License

MIT

Package Sidebar

Install

npm i abstract-type

Weekly Downloads

4

Version

0.4.4

License

MIT

Last publish

Collaborators

  • riceball