@fczbkk/config-mask v1.16.0
Config Mask
Helper that takes care of validating, sanitizing and coercing of complex config objects.
How to use
Install the library via NPM:
npm install @fczbkk/config-mask --saveThen use in your project like this:
import ConfigMask from '@fczbkk/config-mask';Simple value
The simplest use is a coercion of input value.
var numeric_value = new ConfigMask({
type: 'number',
default: 0
});
// use default value when input is missing
numeric_value.sanitze(); // 0
// use default value when input is invalid
numeric_value.sanitize('xxx'); // 0
// use valid value
numeric_value.sanitize(100); // 100
// convert value to expected type if possible
numeric_value.sanitize('100'); // 100Any value
You can use type any to accept any type of input. It will not check the type nor sanitize it to any specific type.
var any_value = new ConfigMask({
type: 'any'
});
any_value.sanitize(); // undefined
any_value.sanitize('aaa') // 'aaa'
any_value.sanitize(123) // '123'You can still use any other options. For example default value, which will be used when input is undefined:
var any_value = new ConfigMask({
type: 'any',
default: 'n/a'
});
any_value.sanitize(); // 'n/a'
any_value.sanitize('aaa') // 'aaa'Or you can use parser to transform input value:
var any_value = new ConfigMask({
type: 'any',
parse: function (input) {return typeof input;}
});
any_value.sanitize(); // 'undefined'
any_value.sanitize('aaa') // 'string'Set
You can define set of valid values that can be used.
var set_value = new ConfigMask({
type: 'set',
values: ['aaa', 'bbb'],
default: 'aaa'
});
// use valid value
set_value.sanitize('aaa'); // 'aaa'
// use default value on missing or invalid input
set_value.sanitize(); // 'aaa'
set_value.sanitize('xxx'); // 'aaa'If you don't set default value, first of the valid values will be used:
var set_value = new ConfigMask({
type: 'set',
values: ['aaa', 'bbb']
});
set_value.sanitize(); // 'aaa'List
Same as set, but for lists of values from defined set.
var list_value = new ConfigMask({
type: 'list',
values: ['aaa', 'bbb']
});
// valid values are fine, invalid ones are filtered out
list_value.sanitize(['aaa', 'xxx', 'bbb']); // ['aaa', 'bbb']
// single value is converted to array
list_value.sanitize('aaa'); // ['aaa']
// default value is always empty array
list_value.sanitize(); // []List of...
Type list_of will produce an array with values of specific type.
- You can use
subtypeproperty to define type of values in array. - You can use
submaskproperty to define ConfigMask that will be applied to values in array. - If both
subtypeandsubmaskproperties are defined,submaskwill be used. - If neither
subtypenorsubmaskproperty is defined, the array will accept values of any types.
var list_of_strings = new ConfigMask({
type: 'list_of',
subtype: 'text'
});
list_of_strings.sanitize(['aaa', null, 123]); // ['aaa', '', '123']
var list_of_objects = new ConfigMask({
type: 'list_of',
submask: {
type: 'object',
properties: {
value: 'number',
unit: 'text'
},
default: {
value: 0,
unit: 'px'
}
}
});
list_of_objects.sanitize([{value: 10, unit: 'cm'}, 'xxx']);
// [{value: 10, unit: 'cm'}, {value: 0, unit: 'px'}]You can use filter property to define function for filtering out unwanted values.
var list_of_short_strings = new ConfigMask({
type: 'list_of',
subtype: 'text',
filter: function (input) {return input.length <= 3;}
});
list_of_short_strings.sanitize(['aaa', 'abcdefgh', 'bbb']); // ['aaa', 'bbb']Custom value types
You can write your own value types, using Coerce.
var array_of_strings = new ConfigMask({
type: {
string: function (input) {
return [input];
},
array: function (input) {
return input.map(function (item) {
return item.toString();
})
}
},
default: []
});
array_of_strings.sanitize(); // []
array_of_strings.sanitize('aaa'); // ['aaa']
array_of_strings.sanitize(['aaa', 'bbb']); // ['aaa', 'bbb']Custom validation
You can create masks with very specific rules using custom validation method.
var positive_number = new ConfigMask({
type: 'number',
validate: function (input) {return number > 0;},
default: 1
});
positive_number.sanitize(10); // 10
positive_number.sanitize(-10); // 1 (default value)To simplify debugging or error reporting, you can use on_invalid method. It will be called when sanitizing the input and it will receive the input as parameter.
var positive_number = new ConfigMask({
type: 'number',
validate: function (input) {return number > 0;},
on_invalid: function (input) {
console.log('Only positive numbers allowed. You have used ' + input + '.');
},
default: 1
});In some cases, it may be helpful to validate the result after it has been sanitized. For example when dealing with complex objects with various sub-properties, where the end result of sanitation may depend on results of sanitation of properties.
var value_with_unit = ConfigMask({
type: 'object',
properties: {
value: {type: 'number'},
unit: {type: 'string'}
},
default: null,
validate_after: function (input) {
// if either `value` or `unit` is not set, sanitize to `nul` (default value)
return input.value !== 0 && value.unit !== '';
}
});Simple objects
You can simply set the value to be an object:
var my_object = new ConfigMask({
type: 'object'
});
my_object.sanitize(); // {}
my_object.sanitize('aaa'); // {}
my_object.sanitize({aaa: 'bbb'}); // {aaa: 'bbb'}You can define a list of properties that the resulting object should have. Properties not on the list will be ignored. Missing properties will be added with undefined value:
var person_name = new ConfigMask({
type: 'object',
properties: ['first_name', 'last_name']
});
var sanitized_name = person_name.sanitize({
first_name: 'John',
occupation: 'programmer'
});
sanitized_name.first_name; // 'John'
sanitized_name.last_name; // undefined
sanitized_name.occupation; // undefined (ignored)Complex objects
This is why I created ConfigMask. Sanitize complex configuration objects without going through all the properties and checking them manually.
var value_config = {
type: 'number',
default: 0
};
var unit_config = {
type: 'set',
values: ['px', '%'],
default: 'px'
};
var size_config = new ConfigMask({
type: 'object',
properties: {
value: value_config,
unit: unit_config
}
});
// use default values when input is missing
size_config.sanitize(); // {value: 0, unit: 'px'}
// add missing properties
size_config.sanitize({value: 100}); // {value: 100, unit: 'px'}
// ignore unknown properties
size_config.sanitize({xxx: 'yyy'}); // {value: 0, unit: 'px'}Keep properties
By default, all undefined properties will be removed:
var my_config = {
type: 'object',
properties: {
aaa: 'text'
}
}
// property `ccc` will be removed
my_config.sanitize({aaa: 'bbb', ccc: 'ddd'}); // {aaa: 'bbb'}If you want to keep undefined properties intact, add keep_property to config with truthy value:
var my_config = {
type: 'object',
properties: {
aaa: 'text'
},
keep_properties: true
}
// property `ccc` will remain unchanged
my_config.sanitize({aaa: 'bbb', ccc: 'ddd'}); // {aaa: 'bbb', ccc: 'ddd'}Nesting
You can nest ConfigMask objects together, creating very complex and interconnected types.
// Both of these objects work as standalone config mask...
var value_config = new ConfigMask({
type: 'number',
default: 0
});
var unit_config = new ConfigMask({
type: 'set',
values: ['px', '%'],
default: 'px'
});
// ... but they are also used in this config mask to create more complex type.
var size_config = new ConfigMask({
type: 'object',
properties: {
value: value_config,
unit: unit_config
}
});Combined configs
If you need to accept various input types in configs, you can use "combined" type. It will sanitize input value through all the submasks and use first non-null result.
var navigation_config = {
type: 'set',
values: ['previous', 'next'],
default: null
};
var index_config = {
type: 'number',
default: 0
}
var combined_config = new ConfigMask({
type: 'combined',
submasks: [navigation_config, index_config]
});
combined_config.sanitize('previous'); // 'previous'
combined_config.sanitize(123); // 123
combined_config.sanitize('xxx'); // 0Cloning to make variations
Sometimes you want to create a variation of existing ConfigMask. For example, you want the same config, but different default value. The easy way to do this is to use clone() method.
var person_age = new ConfigMask({
type: 'number',
default: 0
});
var old_person_age = person_age.clone({default: 60});
person_age.sanitize('xxx'); // 0
old_person_age.sanitize('xxx'); // 60Documentation
Configuration
ConfigMask's configuration object.
Properties
type[(string | Object)] Identifier of item type (e.g. "number", "array") or custom config for Coerce object (https://github.com/InlineManual/coerce/).default[any] Default value to be used when input is invalid or missing.values[Array] Iftypeis "set", this is the list of valid values.properties[Object] Iftypeis "object", this is the list of its properties. The values should beConfigurationobjects.keep_properties[boolean] If type is "object" and "properties" are defined, unspecified properties of the object will not be removed.submasks[Array<(Configuration | ConfigMask)>] List of sub-masks to be used when type is set to "combined". Sub-masks are evaluated in given order. First one that returns non-null value is used.submask[(Configuration | ConfigMask)] Mask to be used when type is set tolist_of. This property has priority oversubtypesubtype[(string | Object)] Type of value allowed to be used when type is set tolist_of.parse[Function] If set, it will be used to transform input before it is being sanitized.validate[Function] When sanitizing, passes parsed input through validator. If it does not pass, default value is used instead.validate_after[Function] Same asvalidate, but applied after the sanitation is done. This is useful for complex object types, where end result of sanitation may depend on result of sanitation of some of the properties.on_invalid[Function] Called when input is evaluated as invalid when sanitizing.filter[Function] If set, it will be used bylist_oftype to filter out values from result.
ConfigMask
Class representing ConfigMask.
constructor
Create ConfigMask.
Parameters
config[Configuration](default {})
setOptions
Sets object's options.
Parameters
configConfiguration
updateOptions
Adds new properties and replaces existing properties in object's options.
Parameters
configConfiguration
sanitize
Applies config mask to input and returns sanitized value.
Parameters
input[any]param[any] Parameter that will be added to all subsequent calls ofsanitize(),parse()andvalidate().
Returns any
parse
Apply parse function on input, return unchanged input if not set.
Parameters
inputparamany Will be passed as second parameter to the parse function.
Examples
Add prefix to all texts.
var prefixed_text = new ConfigMask({
type: 'text',
parse: function (input) {return 'bbb' + input;}
});
prefixed_text.sanitize('aaa'); // 'aaabbb'Returns any
validate
Validates input. Used to check parsed input before being used in sanitation.
Parameters
inputparamany Will be passed as second parameter to the validate function.validation_function[Function](default this._options.validate) Function to be used to validate input.
Examples
Limit maximum length of input.
var max_three_characters = new ConfigMask({
type: 'text',
validate: function (input) {return input.length <= 3;}
});
max_three_characters.sanitize('aaa'); // 'aaa'
max_three_characters.sanitize('aaabbb'); // ''Returns boolean
clone
Creates exact copy of original object, updates the options with new ones.
Parameters
config[Configuration](default {})
Returns ConfigMask
ensureArray
Makes sure that input is an array. If input is undefined, an empty array is returned.
Parameters
inputany
Returns Array
applyFilter
If filter function is defined, applies it to data. Otherwise returns data unchanged.
Parameters
Returns Array
Bug reports, feature requests and contact
If you found any bugs, if you have feature requests or any questions, please, either file an issue at GitHub or send me an e-mail at riki@fczbkk.com.
License
Config Mask is published under the MIT license.
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago