Licence
MIT
Version
0.4.4
Deps
4
Vulns
0
Weekly
0
abstract-type 
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
nameandrequiredattributes.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.ValueTypeproperty: (optional) defaults toValueClass. unless implement your own Value class.
- Properties:
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 valueoptions(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 thewithTypeis true.- aOptions (object):
withType(boolean): whether includes the type info. default to false
- aOptions (object):
- 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.
- Properties:
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
nameonly 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'svaluefrom 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
n = 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
customValidateproperty 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.
- arguments
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.
- (object):
- arguments
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.
- (object):
- arguments
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.
- arguments
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.
- arguments
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.
- arguments
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
- it is the same as
- return
- (object): the created type object instance with the type info options.
- arguments
createValue(value, options):create a value from the type.- alias: create
- arguments
value(Type): the value of this type to createoptions(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 optionsvalue(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.
- arguments
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 optionsvalue(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.
- arguments
validate(value, raiseError, options):validate a specified value whether is valid.- arguments
value(Type): the value to validateraiseError(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.
- arguments
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.
- arguments
- 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.
- return
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.
- arguments
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):
thisobject.
- (object):
- arguments
isValid(): validate the value whether is valid.- return
- (boolean): whether the value is valid.
- return
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 optionswithType(Boolean): whether with type info, defaults to false.
return
- (object): the value and type info(if
withType).
- (object): the value and type info(if
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