Concepts
Conditions
Conditions have various use cases in Eventvisor projects, ranging from filtering events from being tracked to conditionally routing them to different destinations.
Datafile representation#
Eventvisor can store conditions as JSON strings in compact datafiles. This is only a representation change. The string contains the same JSON condition object described on this page. The grammar is part of datafile schema version 1, and SDKs parse it before evaluation. Malformed strings fail closed, so they never accidentally match. Parsed conditions are cached for the active datafile.
Set stringify: false in project configuration or on an individual Target when human-readable datafiles are more important than size.
Condition syntax is designed for consistent evaluation across SDK languages. Regular expressions use a portable subset. Supported flags are g, i, m, and s, with each flag used at most once. Lookaround, named groups, noncapturing groups, backreferences, inline mode groups, atomic groups, and possessive quantifiers are rejected during linting. SDKs also reject them defensively if an unvalidated datafile is loaded.
The before and after operators require a real ISO 8601 date and time with a timezone, such as 2026-01-01T00:00:00Z. Invalid calendar dates are rejected. Semantic version operators require a complete SemVer value such as 1.2.3. Prefixes, partial versions, wildcards, and invalid leading zeroes are rejected. Invalid operands fail closed and do not match.
A condition must use exactly one source selector. Source and transform paths reject empty segments and unsafe object keys such as __proto__, prototype, and constructor.
Anatomy of a condition#
A condition is based on the following properties:
- A source for original value (see sources page), which can be expressed via several different properties like:
sourceattributepayloadlookup
- An
operatorfor the comparison between the source and the value - A
valueto compare against
Operators#
These operators are supported as conditions:
| Operator | Type of attribute | Description |
|---|---|---|
exists | Source is defined | |
notExists | Source is undefined | |
equals | any | Equals to |
notEquals | any | Not equals to |
greaterThan | integer, double | Greater than |
greaterThanOrEquals | integer, double | Greater than or equal to |
lessThan | integer, double | Less than |
lessThanOrEquals | integer, double | Less than or equal to |
contains | string | Contains string |
notContains | string | Does not contain string |
startsWith | string | Starts with string |
endsWith | string | Ends with string |
in | primitive | In array of primitive values |
notIn | primitive | Not in array of primitives |
before | string, date | Date comparison |
after | string, date | Date comparison |
matches | string | Matches regex pattern |
notMatches | string | Does not match regex pattern |
semverEquals | string | Semver equals to |
semverNotEquals | string | Semver not equals to |
semverGreaterThan | string | Semver greater than |
semverGreaterThanOrEquals | string | Semver greater than or equals |
semverLessThan | string | Semver less than |
semverLessThanOrEquals | string | Semver less than or equals |
includes | array | Array includes primitive |
notIncludes | array | Array excludes primitive |
Several examples below showing how attribute source can be used with each of them. You can of course use other sources as well.
equals#
# ...conditions: - attribute: country operator: equals value: usnotEquals#
# ...conditions: - attribute: country operator: notEquals value: usgreaterThan#
# ...conditions: - attribute: age operator: greaterThan value: 21greaterThanOrEquals#
# ...conditions: - attribute: age operator: greaterThanOrEquals value: 18lessThan#
# ...conditions: - attribute: age operator: lessThan value: 65lessThanOrEquals#
# ...conditions: - attribute: age operator: lessThanOrEquals value: 64contains#
# ...conditions: - attribute: name operator: contains value: JohnnotContains#
# ...conditions: - attribute: name operator: notContains value: SmithstartsWith#
# ...conditions: - attribute: name operator: startsWith value: JohnendsWith#
# ...conditions: - attribute: name operator: endsWith value: Smithin#
# ...conditions: - attribute: country operator: in value: - be - nl - lunotIn#
# ...conditions: - attribute: country operator: notIn value: - fr - gb - debefore#
# ...conditions: - attribute: date operator: before value: 2023-12-25T00:00:00Zafter#
# ...conditions: - attribute: date operator: after value: 2023-12-25T00:00:00ZsemverEquals#
# ...conditions: - attribute: version operator: semverEquals value: 1.0.0semverNotEquals#
# ...conditions: - attribute: version operator: semverNotEquals value: 1.0.0semverGreaterThan#
# ...conditions: - attribute: version operator: semverGreaterThan value: 1.0.0semverGreaterThanOrEquals#
# ...conditions: - attribute: version operator: semverGreaterThanOrEquals value: 1.0.0semverLessThan#
# ...conditions: - attribute: version operator: semverLessThan value: 1.0.0semverLessThanOrEquals#
# ...conditions: - attribute: version operator: semverLessThanOrEquals value: 1.0.0exists#
# ...conditions: - attribute: country operator: existsnotExists#
# ...conditions: - attribute: country operator: notExistsincludes#
# ...conditions: - attribute: permissions operator: includes value: writenotIncludes#
# ...conditions: - attribute: permissions operator: notIncludes value: writematches#
# ...conditions: - attribute: email operator: matches value: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ # optional regex flags regexFlags: i # case-insensitiveOrdinary capture groups and character classes are supported. Keep patterns within the portable subset described at the start of this page so the same datafile behaves consistently in every SDK.
notMatches#
# ...conditions: - attribute: email operator: notMatches value: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ # optional regex flags regexFlags: i # case-insensitiveAdvanced conditions#
Conditions can also be combined using and, or, and not operators.
and#
When using and, all direct child conditions must match.
# ...conditions: and: - attribute: country operator: equals value: us - attribute: device operator: equals value: iPhoneBy default if and is not specified directly under conditions, it is implied.
or#
When using or, at least one direct child condition must match.
# ...conditions: or: - attribute: country operator: equals value: us - attribute: country operator: equals value: canot#
not negates the implicit AND of its direct children. A list with two conditions means “not all of these match”.
# ...conditions: not: - attribute: country operator: equals value: usTo express “none of these match”, place an or inside not:
conditions: not: - or: - attribute: country operator: equals value: us - attribute: country operator: equals value: caand, or, and not must contain at least one child.
Complex#
and and or can be combined to create complex conditions:
# ...conditions: - and: - attribute: device operator: equals value: iPhone - or: - attribute: country operator: equals value: us - attribute: country operator: equals value: caYou can also nest and, or, and not operators:
# ...conditions: - not: - or: - attribute: country operator: equals value: us - attribute: country operator: equals value: ca
