/** Abstract class representing a subset of any primitive value type, herein referred to as a _fieldtype_. For example, a hypothetical ```class Email extends Field``` would represent a subset of ```string``` (i.e. strings that are valid email addresses). A class which extends {@linkcode Field} should define the requirements of its _fieldtype_ by overriding {@linkcode Field.parse|Field.prototype.parse}. Instances of {@linkcode Field} are used to validate values and compose {@linkcode Schema|Schemas}. */ export default class Field { static Flags = { /** _OPTIONAL_ denotes that a field should have a default value of null. */ OPT : 0b001 , /** _PRIVATE_ denotes that a field should not be exposed. */ PRV : 0b010 , } ; /** The value to be returned from {@linkcode Field.parse|Field.prototype.parse} when invoked with ```undefined``` or ```null```. Note that providing a defualt value effectively renders the field optional. */ default : any ; /** A bit field representing a set of boolean {@linkcode Field.Flags|flags}. */ flags : number ; /** The error message produced by the last call to {@linkcode Field.parse|Field.prototype.parse}, if it was unsuccessful. */ lastError : string ; param defaultVal param flags constructor ( defaultVal = undefined , flags = null ) { this . default = defaultVal ; this . flags = flags || 0 ; } param flag returns hasFlag ( flag ) { return ! ! ( this . flags & flag ) ; } /** Returns a copy of the {@linkcode Field} instance. */ clone ( ) { const Type = < { new ( ) : Field ; } > this . constructor ; return Object . assign ( new Type ( ) , this ) ; } param value returns async parse ( value ) { this . lastError = null ; if ( value === undefined || value === null ) { if ( this . hasFlag ( Field . Flags . OPT ) && this . default === undefined ) { return null ; } return this . default ; } return value ; } }