Retrieve an object’s property value. Could be a shallow property or a nested property.
objectro.get(
input: object
| function
| (object | function)[],
prop: string
| number
| (string | number)[],
defaultValue?: any
)
const objectro = require("objectro").default;
const input = {
an: {
example: {
of: [
{
nested: {
objects: [1, 2, 3]
}
}
]
}
}
};
get(input, "an.example.of[0].nested.objects[2]");
// -> 3
Assign an object’s property value. Could be a shallow property or a nested property.
objectro.get(
input: object
| function
| any[],
prop: string
| number
| (string | number)[],
value: any
)
const objectro = require("objectro").default;
const input = {
an: {
example: {
of: [
{
nested: {
objects: [1, 2, 3]
}
}
]
}
}
};
set(input, "an.example.of[0].nested.objects[2]", "nice!");
get(input, "an.example.of[0].nested.objects[2]");
// -> "nice!"
Transforming allows you to take an input object and describe how you want its property names and values to be reformatted.
objectro.transform(
input: object,
propertyName: string
| number
| string[]
| number[]
| TransformMap
): object
Transforming will allow you to:
const objectro = require("objectro").default;
let input = {
test1: 1,
testB: "2",
testC: "03,04,05"
};
// This transform map specifies how we want to reformat the input object
let outputMap = {
// Takes `test1` from input and puts it on the output as `testA`
test1: "testA",
// Takes `testB` from input and formats its value on the
// output as `testB`
testB: value => parseInt(value, 10),
// Takes `testC` from input and formats its value on the
// output as `testC`, `testD` and `testE`
testC: value => {
let [testC, testD, testE] = value.split(",").map(val => parseInt(val, 10));
return {
testC,
testD,
testE
};
}
};
objectro.transform(input, outputMap);
// Outputs:
// {
// testA: 1,
// testB: 2,
// testC: 3,
// testD: 4,
// testE: 5
// }
It’s worth noting that you don’t need to use a transform map if you only want to pluck certain values from an object. Instead of transform maps, you can use string values (or arrays of strings) to mark the properties you do want to keep:
const objectro = require("objectro").default;
let input = {
testA: "Hello",
testB: "This is a simple test",
testC: "Don't need this property",
testD: "Rename this property to testC"
};
objectro.transform(input, "testA", "testB");
// Outputs:
// {
// testA: "Hello",
// testB: "This is a simple test"
// }
You can combine all accepted argument types and objectro.transform
will apply them in sequence:
objectro.transform(input, "testA", ["testB"], { testD: "testC" });
// Outputs:
// {
// testA: "Hello",
// testB: "This is a simple test",
// testC: "Rename this property to testC"
// }
{
fromPropertyName: string
| map: TransformMap
| formatFn: Function(
value: any,
propName: string,
input: object,
output: object
)
}
A transform map is an object which maps an input object’s structure from one model to another.
The transform map will generally mimic the input object’s structure, however the values of each property can vary:
{
fromPropertyName: "toPropertyName";
}
The above transforms from one property name on the input object to a different property name on the output object.
{
fromPropertyName: {
nestedObjectFromPropertyName: "toPropertyName";
}
}
If fromPropertyName
is a nested object, you can nest transform maps that will be applied to that nested object. Note that the nested objects will be placed under the fromPropertyName
– if you need to change the parent property name, you can use a formatFn
.
Using the formatFn
method also allows more control over formatting the value and where that value will be placed in the output object.
{
fromPropertyName:
(fromPropertyValue, propName, inputObject, outputObject) => {
// Return either a new non-object value to be the new property
// value, or return an object to merge into the output object.
// This method is good for when you need to split one value into
// multiple values or multiple properties on the output object.
return {
toPropertyName: fromPropertyValue
}
}
}
}
objectro.validate(
input: any,
rules: ValidationRules,
options: ValidationOptions
): boolean
You can verify an object’s structure and its contents using objectro.validate
. You can also combine multiple rules and use rule modifiers to change behaviours of those rules.
Validation allows you to:
The simplest rules to use are:
has
: Check object has a property or if a property has a value.match
: Apply rules to an object’s propertiesThe following rule modifiers change the behaviour of any nested rules:
any
: match any rule given (this is the default behaviour)all
: match all rules givennot
: negate the returned valueconst objectro = require("objectro").default;
function isDefined(input) {
return input !== null && input !== undefined;
}
function validateExample(input) {
return objectro.validate(input, {
// All nested rules must positively match to be valid
all: {
// Check that the input type is an object
type: "object",
// Check if the input object has a "name" property
// (we don't care if it's not defined)
has: "name",
// Run specific rules against multiple properties
match: {
// We can specify multiple rules for each named property
age: {
// These rules check if the "age" property is a string
// and greater than or equal to 18
type: "string",
gte: 18
},
// Here we can enforce that we want the name to be defined
// by using a custom function to validate the value
name: isDefined
}
}
});
}
validateExample({}); // false
validateExample({ example: true }); // false
validateExample("{}"); // false
validateExample({ name: "Example" }); // false
validateExample({ age: "55" }); // false
validateExample({ name: "Example", age: 16 }); // false
validateExample({ name: null, age: 35 }); // false
validateExample({ name: "Example", age: 35 }); // true
Using the ValidationOptions.data
option, we can supply meta-data that can be validated if the original input object does not contain the referenced property:
const objectro = require("objectro").default;
const input = {
name: "Matt Scheurich",
nationality: "nz",
location: "fr",
languages: ["en", "fr"]
};
const canUnderstandEachOther = lang => {
objectro.validate(
input,
{
all: {
has: {
// Check if the languages field has the locale value assigned
languages: lang,
// This property is not on the original input object
// however we do feed it via the `ValidationOptions.data` value
systemLanguages: lang
}
}
},
{
data: {
systemLanguages: ["en", "de"]
}
}
);
};
canUnderstandEachOther("fr");
// false: input.languages has "fr", but data.systemLanguages doesn't
canUnderstandEachOther("de");
// false: data.systemLanguages has "de", but input.languages doesn't
canUnderstandEachOther("en"); // true
There are three types of rules:
Rule | Type | Description |
---|---|---|
any |
Modifier | Return true if any nested rules match |
all |
Modifier | Return true only if all nested rules match |
not |
Modifier | Negate the return value: true ⇒ false , false ⇒ true |
has |
Expression, Map | Check for existence of properties (using a string or Array<String> ), or for possible values (using an object ) |
match |
Map | Validate properties using nested ValidationRules objects for each property name |
type |
Expression | Check if input matches a specific type: string , number , integer , float , boolean , array , arrayLike , set , map , object , objectLike , plainObject , function (more) |
eq |
Expression | Equality (== ) |
eqs |
Expression | Strict equality (=== ) |
gt |
Expression | Greater than |
gte |
Expression | Greather than or equals |
lt |
Expression | Less than |
lte |
Expression | Less than or equals |
re |
Expression | RegExp test |
startsWith |
Expression | Check if input starts with a value (can be affected by caseSensitive ) |
endsWith |
Expression | Check if input ends with a value (can be affected by caseSensitive ) |
contains |
Expression | Check if input (string or array) contains value (can be affected by caseSensitive if input is string) |
includesAny |
Expression | Check if input includes any values |
includesAll |
Expression | Check if input includes all values |
There are more specialised rules available.
Option | Type | Description |
---|---|---|
matchAll |
boolean | Return true only if all rules within the ValidationRules object match |
negateMatch |
boolean | Return the opposite of the match’s result |
skipMissingProps |
boolean | Pass any properties on the input object if they don’t exist or are undefined |
caseSensitive |
boolean | Enable or disable case sensitivity mode |
data |
object | Supply extra data to validate against. If the input object does not contain the property within the rules, objectro.validate will then check this object. |