Skip to content

Latest commit

 

History

History
763 lines (520 loc) · 16.6 KB

README.md

File metadata and controls

763 lines (520 loc) · 16.6 KB

node-expression

npm install @orioro/expression

Framework of expression interpreters.

Use cases

Data querying

Main modules: comparison and object

const person = {
  givenName: 'João',
  middleName: 'Cruz',
  familyName: 'Silva',
  age: 32,
  interests: ['sport', 'music', 'books'],
  mother: {
    givenName: 'Maria',
    familyName: 'Cruz',
    age: 57
  },
  father: {
    givenName: 'Pedro',
    familyName: 'Silva',
    age: 56
  }
}

const context = {
  interpreters,
  scope: { $$VALUE: person }
}

// Simple equality comparison
evaluate(context, ['$objectMatches', { givenName: 'João' }]) // true
evaluate(context, ['$objectMatches', { givenName: 'Maria' }]) // false

// Use dot (.) path notation to access nested properties
evaluate(context, ['$objectMatches', {
  'mother.age': { $gte: 20, $lte: 50 },
  'father.age': { $gte: 20, $lte: 50 }
}]) // false

Tree structure formatting

TODO

Conditional evaluation

TODO
// const context = {
//   interpreters,
//   scope: {
//     $$VALUE: {
//       name: 'João',
//       interests: ['music', 'sports']
//       age: 30
//     }
//   }
// }

// const cases = [
//   [['$objectMatches', {
//     interests: {
//       $arrayIncludes: 'music'
//     }
//   }]]
// ]

API

Built-in expressions:

External expression modules:

Array

$arrayIncludes(searchValue, array)

Equivalent of Array.prototype.includes.

  • searchValue {*}
  • array {Array}
  • Returns: includes {Boolean}
$arrayIncludesAll(searchValues, array)

Similar to $arrayIncludes, but receives an array of values to be searched for and returns whether the context array contains all of the searched values.

  • searchValues {Array}
  • array {Array}
  • Returns: includesAll {Boolean}
$arrayIncludesAny(searchValue, array)

Similar to $arrayIncludes, but returns true if any of the searched values is in the array.

  • searchValue {Array}
  • array {Array}
  • Returns: includesAny {Boolean}
$arrayLength(array)
  • array {Array}
  • Returns: length {Number}
$arrayReduce(reduceExp, start, array)
$arrayMap(mapExp, array)
$arrayEvery(testExp, array)

Array.prototype.every

Result is similar to logical operator $and. Main difference (and reason for existence as isolate expression) is that $arrayEvery exposes array iteration variables: $$PARENT_SCOPE, $$VALUE, $$INDEX, $$ARRAY

$arraySome(someExp, array)

Array.prototype.some

$arrayFilter(queryExp, array)
  • queryExp {Boolean}
  • array {Array}
$arrayFindIndex(queryExp, array)
  • queryExp {Boolean}
  • array {Array}
$arrayIndexOf(value, array)
  • value {*}
  • array {Array}
$arrayFind(queryExp, array)
  • queryExp {Boolean}
  • array {Array}
$arrayReverse(array)
  • array {Array}
$arraySort(sort, array)
  • sort {String | Expression | [Expression, string]}
  • array {Array}
$arrayPush(valueExp, array)
  • valueExp {*}
  • array {Array}
$arrayPop(array)
  • array {Array}
$arrayUnshift(valueExp, array)
  • valueExp {*}
  • array {Array}
$arrayShift(array)
  • array {Array}
$arraySlice(start, end, array)
  • start {Number}
  • end {Number}
  • array {Array}
  • Returns: {Array}
$arrayReplace(indexOrRange, values, array)
  • indexOrRange {Number | [Number, Number]}
  • values {Array}
  • array {Array}
  • Returns: {Array}
$arrayAddAt(index, values, array)

Adds items at the given position.

  • index {Number}
  • values {* | Array}
  • array {Array}
  • Returns: resultingArray {Array} The array with items added at position
$arrayRemoveAt(index, countExp, array)
  • index {Number}
  • countExp {Number}
  • array {Array}
  • Returns: resultingArray {Array} The array without the removed item
$arrayJoin(separator, array)
  • separator {String}
  • array {Array}
  • Returns: {String}
$arrayAt(index, array)
  • index {Number}
  • array {Array}
  • Returns: value {*}

Boolean

$boolean(value)
  • value {*}
  • Returns: {Boolean}

Comparison

$eq(referenceExp, valueExp)

Checks if the two values

  • referenceExp {*}
  • valueExp {*}
  • Returns: {Boolean}
$notEq(referenceExp, valueExp)
  • referenceExp {*}
  • valueExp {*}
  • Returns: {Boolean}
$in(arrayExp, valueExp)

Checks whether the value is in the given array.

  • arrayExp {Array}
  • valueExp {*}
  • Returns: {Boolean}
$notIn(arrayExp, valueExp)

Checks whether the value is not in the given array.

  • arrayExp {Array}
  • valueExp {*}
  • Returns: {Boolean}
$gt(referenceExp, valueExp)

Greater than value > threshold

  • referenceExp {Number}
  • valueExp {Number}
  • Returns: {Boolean}
$gte(referenceExp, valueExp)

Greater than or equal value >= threshold

  • referenceExp {Number}
  • valueExp {Number}
  • Returns: {Boolean}
$lt(referenceExp, valueExp)

Lesser than value < threshold

  • referenceExp {Number}
  • valueExp {Number}
  • Returns: {Boolean}
$lte(referenceExp, valueExp)

Lesser than or equal value <= threshold

  • referenceExp {Number}
  • valueExp {Number}
  • Returns: {Boolean}
$matches(criteriaExp, valueExp)

Checks if the value matches the set of criteria.

  • criteriaExp {Object}
  • valueExp {Number}
  • Returns: {Boolean}

Functional

$pipe(expressions)
  • expressions {Expression[]}
  • Returns: pipeResult {*}
$try(expressionOrValue, catchExpressionOrValue)

Logical

$and(expressionsExp)
  • expressionsExp {Array}
  • Returns: {Boolean}
$or(expressionsExp)
  • expressionsExp {Array}
  • Returns: {Boolean}
$not(expressionsExp)
  • expressionsExp {Array}
  • Returns: {Boolean}
$nor(expressionsExp)
  • expressionsExp {Array}
  • Returns: {Boolean}
$xor(expressionA, expressionB)
  • expressionA {Boolean}
  • expressionB {Boolean}
  • Returns: {Boolean}
$if(conditionExp, thenExp, elseExp)
$switch(cases, defaultExp)
  • cases {Array}
  • defaultExp {Expression}
  • Returns: result {*}
$switchKey(cases, defaultExp, ValueExp)
  • cases {Cases[]}
    • 0 {String}
    • 1 {*}
  • defaultExp {*}
  • ValueExp {String}
  • Returns: {*}

Math

$mathSum(sum, base)
  • sum {Number}
  • base {Number}
  • Returns: result {Number}
$mathSub(subtract, base)
  • subtract {Number}
  • base {Number}
  • Returns: result {Number}
$mathMult(multiplier, base)
  • multiplier {Number}
  • base {Number}
  • Returns: result {Number}
$mathDiv(divisor, dividend)
  • divisor {Number}
  • dividend {Number}
  • Returns: result {Number}
$mathMod(divisor, dividend)
  • divisor {Number}
  • dividend {Number}
  • Returns: result {Number}
$mathPow(exponent, base)
  • exponent {Number}
  • base {Number}
  • Returns: result {Number}
$mathAbs(value)
  • value {Number}
  • Returns: result {Number}
$mathMax(otherValue, value)
  • otherValue {Number | Number[]}
  • value {Number}
  • Returns: result {Number}
$mathMin(otherValue, value)
  • otherValue {Number | Number[]}
  • value {Number}
  • Returns: result {Number}
$mathRound(value)
  • value {Number}
  • Returns: result {Number}
$mathFloor(value)
  • value {Number}
  • Returns: result {Number}
$mathCeil(value)
  • value {Number}
  • Returns: result {Number}

Number

$numberInt(radix, value)
  • radix {Number}
  • value {*}
  • Returns: {Number}
$numberFloat(value)
  • value {*}
  • Returns: {Number}

Object

$objectMatches(criteriaByPath, value)
  • criteriaByPath {Object}
  • value {Object}
  • Returns: matches {Boolean}
$objectFormat(format, source)
  • format {Object | Array}
  • source {*}
  • Returns: object {Object | Array}
$objectDefaults(defaultValuesExp, base)
  • defaultValuesExp {Object}
  • base {Object}
  • Returns: {Object}
$objectAssign(values, base)
  • values {Object}
  • base {Object}
  • Returns: {Object}
$objectKeys(object)
  • object {Object}
  • Returns: {String[]}

String

$string(value)
  • value {*}
  • Returns: {String}
$stringStartsWith(query, str)
  • query {String}
  • str {String}
  • Returns: {Boolean}
$stringEndsWith(query, str)
  • query {String}
  • str {string}
  • Returns: {Boolean}
$stringLength(str)
  • str {String}
  • Returns: {Number}
$stringSubstr(start, end, str)
  • start {Number}
  • end {Number}
  • str {String}
$stringConcat(concat, base)
  • concat {String | String[]}
  • base {String}
  • Returns: {String}
$stringTrim(str)
  • str {String}
  • Returns: {String}
$stringPadStart(targetLengthExp, padStringExp, str)
  • targetLengthExp {Number}
  • padStringExp {String}
  • str {String}
  • Returns: {String}
$stringPadEnd(targetLengthExp, padStringExp, str)
  • targetLengthExp {Number}
  • padStringExp {String}
  • str {String}
  • Returns: {String}
$stringToUpperCase(value)
  • value {String}
  • Returns: {String}
$stringToLowerCase(value)
  • value {String}
  • Returns: {String}
INTERPOLATION_REGEXP

/${\s*([\w$.]+)\s*}/g

RegExp used for matching interpolation expressions. Allows a non-interrupted sequence of alphanumeric chars ([A-Za-z0-9_]), dollar signs ($) and dots (.) wrapped in curly braces ({}) with or without any number of whitespace chars (' ') between braces and the value identifier.

Some resources on RegExp safety concerning RegExp Denial of Service (ReDOS) through Catastrophic backtracking, for future study and reference:

$stringInterpolate(data, template)
  • data {Object | Array}
  • template {String}

Type

$type(valueExp)
  • valueExp {*}
  • Returns: type {String} Possible values:
    • string
    • regexp
    • number
    • bigint
    • nan
    • null
    • undefined
    • boolean
    • function
    • object
    • array
    • date
    • symbol
    • map
    • set
    • weakmap
    • weakset
$isType(type, value)
  • type {ExpectedType}
  • value {*}
  • Returns: {Boolean}

Value

$value(path, defaultExp)
  • path {String}
  • defaultExp {*}
  • Returns: value {*}
$literal(value)
  • value {*}
  • Returns: {*}
$evaluate(expression, scope)
  • expression {Expression}
  • scope {Object}
  • Returns: {*}