Skip to content

Rules aliasing ​

With rules aliasing you can create custom rules without writing code and assign your own error codes to them. Aliased rules work across all implementations, as they are just data structures.

An alias looks like this:

js
{
    name: ALIAS_NAME,
    rules: ALIAS_RULES,
    error: ERROR_CODE // optional
}

If error is not set, the validator returns the errors of the alias rules.

js
{
    name: 'valid_address',
    rules: { nested_object: {
        country: 'required',
        city: 'required',
        zip: 'positive_integer'
    }}
}

{
    name: 'adult_age',
    rules: ['positive_integer', { min_number: 18 }],
    error: 'WRONG_AGE'
}

You can also use aliased rules inside other aliased rules.

Usage example ​

Let's assume you have this data:

js
{
    name: 'Viktor',
    age: 30,
    address: {
        country: 'Ukraine',
        city: 'Kyiv',
        zip: '11111'
    }
}

and these validation rules for it:

js
{
    name: 'required',
    age: ['required', 'positive_integer', { min_number: 18 }],
    address: ['required', { nested_object: {
        country: 'required',
        city: 'required',
        zip: 'positive_integer'
    }}]
}

You use address in many objects (the user address in a user, the office address in an office, and so on) and want to reuse the same address rules everywhere. Without aliases you have two options:

  1. Write a custom rule valid_address. It takes time and code, and the rule cannot be stored in a serialized JSON file.
  2. Assign the rules to a variable and reuse it. It is easy, and the address rules can be stored in JSON, but the rules that use them cannot. And you cannot redefine the error code for the address.

Since v0.4 there is a third option: rules aliasing.

You register aliases for complex rules. How you register an alias depends on the implementation, but how you describe and use it is covered by the specification. So you can store aliases in JSON files and use them across different implementations.

js
// Aliasing pseudo code
validator.registerAliasedRule({
    name: 'valid_address',
    rules: { nested_object: {
        country: 'required',
        city: 'required',
        zip: 'positive_integer'
    }}
})

validator.registerAliasedRule({
    name: 'adult_age',
    rules: ['positive_integer', { min_number: 18 }]
})

// Usage
{
    name: 'required',
    age: ['required', 'adult_age'],
    address: ['required', 'valid_address']
}

You can also add your own error codes for the aliases:

js
validator.registerAliasedRule({
    name: 'valid_address',
    rules: { nested_object: {
        country: 'required',
        city: 'required',
        zip: 'positive_integer'
    }},
    error: 'WRONG_ADDRESS'
})

If validation of the address fails, you get this error:

js
{
    address: 'WRONG_ADDRESS'
}

Recipe: ulid ​

ULID is not a standard rule, it was left out of LIVR 2.5. An alias with like and its own error code covers it. A ULID is 26 characters of Crockford's Base32 in uppercase, and the first one is 0–7:

Live example · edit rules or inputOpen in playground
aliases
rules
input
Validoutput
{
  "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV"
}

This is the alias of the 2.5 test suite. A lowercase ULID gives WRONG_ULID. To accept it and return the canonical uppercase form, add to_uc before like: rules: ['to_uc', { like: '^[0-7][0-9A-HJKMNP-TV-Z]{25}$' }].

Try it ​

Live example · edit rules or inputOpen in playground
aliases
rules
input
Invaliderrors
{
  "age": "WRONG_AGE",
  "address": "WRONG_ADDRESS"
}
Test suite cases 6

These cases come straight from the LIVR test suite that every implementation runs. Edit them to see how the rule behaves.

aliases_positive/01-adult_ageOpen in playground
aliases
rules
input
Validoutput
{
  "age1": 32,
  "age2": 33,
  "age3": 35,
  "age4": 36,
  "empty_age": "",
  "age1_custom_error": 37,
  "age2_custom_error": 38,
  "age3_custom_error": 100,
  "age4_custom_error": 110
}
Matches test suiteexpected output
{
  "age1": 32,
  "age2": 33,
  "age3": 35,
  "age4": 36,
  "empty_age": "",
  "age1_custom_error": 37,
  "age2_custom_error": 38,
  "age3_custom_error": 100,
  "age4_custom_error": 110
}
View files on GitHub
aliases_positive/02-addressOpen in playground
aliases
rules
input
Validoutput
{
  "address": {
    "street": "My street",
    "zip": 1232131,
    "city": "Kyiv"
  },
  "address_custom_error": {
    "street": "My street",
    "zip": 12312,
    "city": "Kharkiv"
  }
}
Matches test suiteexpected output
{
  "address": {
    "street": "My street",
    "zip": 1232131,
    "city": "Kyiv"
  },
  "address_custom_error": {
    "street": "My street",
    "zip": 12312,
    "city": "Kharkiv"
  }
}
View files on GitHub
aliases_positive/03-adult_age_in_userOpen in playground
aliases
rules
input
Validoutput
{
  "user": {
    "name": "koorchik",
    "age1": 20,
    "age2": 40
  },
  "user_custom_error": {
    "name": "koorchik",
    "age1": 33,
    "age2": 22
  }
}
Matches test suiteexpected output
{
  "user": {
    "name": "koorchik",
    "age1": 20,
    "age2": 40
  },
  "user_custom_error": {
    "name": "koorchik",
    "age1": 33,
    "age2": 22
  }
}
View files on GitHub
aliases_negative/01-adult_ageOpen in playground
aliases
rules
input
Invaliderrors
{
  "age3": "TOO_LOW",
  "age4": "NOT_POSITIVE_INTEGER",
  "age3_custom_error": "WRONG_AGE",
  "age4_custom_error": "WRONG_AGE"
}
Matches test suiteexpected errors
{
  "age3": "TOO_LOW",
  "age4": "NOT_POSITIVE_INTEGER",
  "age3_custom_error": "WRONG_AGE",
  "age4_custom_error": "WRONG_AGE"
}
View files on GitHub
aliases_negative/02-addressOpen in playground
aliases
rules
input
Invaliderrors
{
  "address": {
    "street": "REQUIRED",
    "zip": "NOT_POSITIVE_INTEGER",
    "city": "NOT_ALLOWED_VALUE"
  },
  "address_custom_error": "WRONG_ADDRESS"
}
Matches test suiteexpected errors
{
  "address": {
    "street": "REQUIRED",
    "zip": "NOT_POSITIVE_INTEGER",
    "city": "NOT_ALLOWED_VALUE"
  },
  "address_custom_error": "WRONG_ADDRESS"
}
View files on GitHub
aliases_negative/03-adult_age_in_userOpen in playground
aliases
rules
input
Invaliderrors
{
  "user": {
    "name": "REQUIRED",
    "age1": "TOO_LOW",
    "age2": "WRONG_AGE"
  },
  "user_custom_error": "WRONG_USER"
}
Matches test suiteexpected errors
{
  "user": {
    "name": "REQUIRED",
    "age1": "TOO_LOW",
    "age2": "WRONG_AGE"
  },
  "user_custom_error": "WRONG_USER"
}
View files on GitHub