abstract-type 

The abstract-type library includes the abstract Type
class for serializing/deserializing type info and validating value.
Concepts
- Primitive Types
- All registered types are primitive types.
- It's the type class on the global type factory.
- 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 actual value of this type.
- Virtual Types:
- Url, telephone, Positive number
Usage
Create the number type
The type has a name and can verify whether a value belongs to that type, and serialize(deserialize) type and value.
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
- Static Members:
- Properties:
$attributes
(Properties): the attributes of this type.
value
: optional the default value if any
required
(Boolean): whether it's required(MUST HAVE).
customValidate
(value: any, options?)=>boolean: callback function
- Methods:
getProperties(): PropDescriptors
- Instance Members:
- Properties:
$attributes
(object): the attributes of this type.
value
: store the value here.
- 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.
clone()
: clone this value object.
assign(value, options)
: assign the value.
aOptions
(object):
checkValidity
(boolean): defaults to true.
-
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.
Notes:
- Serialize
Type
Class and instance will not export the default value of attributes
skipDefault=false
if you wanna export the default value of attributes
import { Type, register, defineProperties } from 'abstract-type'
export class NumberType extends Type {
static toValue(aValue): number | undefined {
if (!isNaN(aValue)) aValue = Number(aValue)
else aValue = undefined
return aValue
}
declare static min: number | undefined
declare static max: number | undefined
declare min: number | undefined
declare max: number | undefined
_isValid(value) {
return isNumber(value)
}
_validate(aValue, aOptions) {
const TheType = this['Class'] || this.constructor
if (typeof aValue === 'string') aValue = TheType.toValue(aValue)
let result = this._isValid(aValue)
if (result) {
const vMin = aOptions.min
const vMax = aOptions.max
if (vMin != null) {
result = aValue >= vMin
if (!result) {
this.error('should be equal or greater than minimum value: ' + vMin)
}
}
if (result && vMax != null) {
result = aValue <= vMax
if (result) {
this.error('should be equal or less than maximum value: ' + vMax)
}
}
}
return result
}
}
defineProperties(NumberType, {
min: {
type: 'Number',
},
max: {
type: 'Number',
},
})
register(NumberType)
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'))
require('number-type')
var number = Type('Number')
assert.equal(number, Type('Number'))
var num = Type('Number', {min:1, max:6})
assert.notEqual(number, num)
var NumberType = Type.registeredClass('Number')
var TPositiveNumber = Type('Number', {min:0, cached: 'PositiveNumber'})
assert.notOk(TPositiveNumber.isValid(-1))
assert.ok(TPositiveNumber.isValid(1))
var n = TPositiveNumber.create(123)
n = TPositiveNumber.createValue(123)
assert.ok(n.isValid())
assert.equal(Number(n) + 3, 126)
var N = Type('/type/AbstractNumber/Number/PositiveNumber')
assert.equals(N, TPositiveNumber);
API
Type = require('abstract-type')
It's the abstract type info class and the type info manager.
-
Type.getType([typeName, ]options)
: get a the type info class from the global factory.
- 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:
var TNumber = Type('number')
TNumber = Type({name: 'number'})
TNumber = NumberType()
var TPositiveNumber = Type('number', {min:0})
assert.notEqual(TPositiveNumber, TNumber)
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.
-
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
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.
TODO
- compare(value1, value2) and equals(value1, value2) to compare value.
License
MIT