Self-validation
parent
9a67ab46ee
commit
fd140bfa31
|
@ -5,8 +5,9 @@
|
|||
* - Uses literal definitions (unlike, for example, Joi)
|
||||
* - Simpler than JSON schema, but convertible to it
|
||||
* - Supports comments and convenient user-readable validation errors
|
||||
* - Coerces decimal strings to numbers
|
||||
* - Coerces scalars to single-element arrays
|
||||
* - Converts strings to numbers if possible
|
||||
* - Converts scalars to single-element arrays
|
||||
* - Validates its own meta-type
|
||||
*
|
||||
* (c) Vitaliy Filippov 2019+
|
||||
*
|
||||
|
@ -100,7 +101,7 @@ class ServerPropTypes
|
|||
{
|
||||
bad = {
|
||||
path: [ i, ...(st.error.path||[]) ],
|
||||
name: '№'+i + (st.error.name ? ' - '+st.error.name : ''),
|
||||
name: '№'+(i+1) + (st.error.name ? ' - '+st.error.name : ''),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
@ -128,7 +129,7 @@ class ServerPropTypes
|
|||
{
|
||||
bad = {
|
||||
path: [ i, ...(st.error.path||[]) ],
|
||||
name: '№'+i + (st.error.name ? ' - '+st.error.name : ''),
|
||||
name: '№'+(i+1) + (st.error.name ? ' - '+st.error.name : ''),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
@ -148,7 +149,7 @@ class ServerPropTypes
|
|||
}
|
||||
break;
|
||||
case 'object':
|
||||
if (typeof v != 'object' || v instanceof Array || type.required && !v)
|
||||
if (v != null && typeof v != 'object' || v instanceof Array || type.required && !v)
|
||||
{
|
||||
bad = true;
|
||||
}
|
||||
|
@ -366,12 +367,21 @@ ServerPropTypes.metaType = {
|
|||
spt: {
|
||||
type: 'one',
|
||||
of: [
|
||||
{ comment: 'Reference to another type', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'ref' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
ref: { type: 'string', comment: 'Type reference', required: true },
|
||||
} },
|
||||
{ comment: 'Any type', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'any' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
} },
|
||||
{ comment: 'String', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'string' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
regex: { type: 'string', comment: 'Regular expression' },
|
||||
|
@ -379,12 +389,14 @@ ServerPropTypes.metaType = {
|
|||
} },
|
||||
{ comment: 'String-coded decimal', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'decimal' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
decimals: { type: 'int', comment: 'Allowed decimal places' },
|
||||
} },
|
||||
{ comment: 'Number', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'num' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
min: { type: 'num', comment: 'Minimum value' },
|
||||
|
@ -392,6 +404,7 @@ ServerPropTypes.metaType = {
|
|||
} },
|
||||
{ comment: 'Integer', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'int' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
min: { type: 'int', comment: 'Minimum value' },
|
||||
|
@ -399,16 +412,19 @@ ServerPropTypes.metaType = {
|
|||
} },
|
||||
{ comment: 'ID (positive integer or NULL)', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'id' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
} },
|
||||
{ comment: 'Boolean', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'bool' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
} },
|
||||
{ comment: 'Array', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'array' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
of: { type: 'ref', ref: 'anytype', required: true, comment: 'Array item type' },
|
||||
|
@ -417,12 +433,14 @@ ServerPropTypes.metaType = {
|
|||
} },
|
||||
{ comment: 'Tuple (fixed-length array)', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'array' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
items: { type: 'array', of: { type: 'ref', ref: 'anytype' }, required: true, comment: 'Tuple item types' },
|
||||
} },
|
||||
{ comment: 'Unstructured hash', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'object' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
of: { type: 'ref', ref: 'anytype', required: true, comment: 'Hash item type' },
|
||||
|
@ -431,18 +449,21 @@ ServerPropTypes.metaType = {
|
|||
} },
|
||||
{ comment: 'Structured object', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'object' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
items: { type: 'object', of: { type: 'ref', ref: 'anytype' }, required: true, comment: 'Field types' },
|
||||
} },
|
||||
{ comment: 'Enum of constants', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'enum' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
of: { type: 'array', minLength: 1, required: true, comment: 'Constants' },
|
||||
of: { type: 'array', of: 'any', minLength: 1, required: true, comment: 'Constants' },
|
||||
} },
|
||||
{ comment: 'One of types', type: 'object', items: {
|
||||
type: { type: 'enum', of: [ 'one' ] },
|
||||
refs: { type: 'object', of: { type: 'ref', ref: 'anytype' } },
|
||||
required: { type: 'bool', comment: 'Item is required' },
|
||||
comment: { type: 'string', comment: 'Item comment' },
|
||||
of: { type: 'array', of: { type: 'ref', ref: 'anytype' }, minLength: 1, required: true, comment: 'Type options' },
|
||||
|
|
Loading…
Reference in New Issue