addPreprocessFn2Functional

const addPreprocessFn2 = require('@eluvio/elv-js-helpers/Functional/addPreprocessFn2')
(* → *) → ((*, *) → *) → ((*, *) → *)
λcurried function
Parameters
  • function(unnamed)

    The 1-input preprocessing function

  • function(unnamed)

    The 2-input function to add preprocessor to

  • Returns:function

    A 2-input function that preprocesses its inputs

Given a 1-input preprocessing function p and a 2-input function f, returns a new function that will apply the preprocessing function to each input before executing f, i.e. (arg1, arg2) => f(p(arg1), p(arg2)). Useful for cleaning up inputs to a function.

'use strict'
const isString = require('@eluvio/elv-js-helpers/Boolean/isString')

const addPreprocessFn2 = require('@eluvio/elv-js-helpers/Functional/addPreprocessFn2')

const strOrNumToNum = x => isString(x) ? Number(x) : x

const add = (x, y) => x + y

const lenientAdd = addPreprocessFn2(strOrNumToNum, add)

lenientAdd(42, 1)                           //=> 43

lenientAdd('42', 1)                         //=> 43

lenientAdd(42, '1')                         //=> 43

lenientAdd('42', '1')                       //=> 43

// function is curried: call with 1 argument to obtain a function that will add the given preprocessor to other functions

const allowStringNumInputs = addPreprocessFn2(strOrNumToNum)

const mult = (x, y) => x * y

const lenientMult = allowStringNumInputs(mult)

lenientMult(42, '42')                       //=> 1764

// call with 3 arguments to obtain a 1-input function that will preprocess its input

const lenientMult42 = addPreprocessFn2(strOrNumToNum, mult, '42')

lenientMult42('42')                         //=> 1764

// call with 4 arguments to obtain final value instead of a function

const x = 42
const y = '42'

addPreprocessFn2(strOrNumToNum, add, x, y)  //=> 84

addSecondsDatetime

const addSeconds = require('@eluvio/elv-js-helpers/Datetime/addSeconds')
Date → Number → Date
λcurried function
Parameters
  • Numberseconds

    The number of seconds to add

  • Datedatetime

    Javascript Date object to add to

  • Returns:Date

Adds a specified number of seconds to a Javascript Date object and returns a new Date

'use strict'
const addSeconds = require('@eluvio/elv-js-helpers/Datetime/addSeconds')

const d = new Date('2022-01-01T07:30:00Z')

// Note that following depends on environment's locale settings (shown values are for locale 'en-US')

addSeconds(3600, d).toUTCString()   //=> 'Sat, 01 Jan 2022 08:30:00 GMT'

addSeconds(-3600, d).toUTCString()  //=> 'Sat, 01 Jan 2022 06:30:00 GMT'

andFunctional

const and = require('@eluvio/elv-js-helpers/Functional/and')
(a → Boolean | Pred a) → (a → Boolean | Pred a) → a → Boolean
λcurried function
Parameters
  • function(unnamed)

    First function that returns a Boolean

  • function(unnamed)

    Second function that returns a Boolean

  • Returns:function

    Function which takes input, passes to both input functions, and then combines return values with logical AND

Passthrough for the and() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given two predicate functions (a -> Boolean), returns a function that combines the two using logical AND.

'use strict'
const and = require('@eluvio/elv-js-helpers/Functional/and')

const isEven = x => (x % 2) === 0
const isNegative = x => x < 0

const isNegEven = and(isEven, isNegative)

isNegEven(3)         //=> false
isNegEven(2)         //=> false
isNegEven(-2)        //=> true

AnyModelModel

const AnyModel = require('@eluvio/elv-js-helpers/Model/AnyModel')
* → *
Parameters
  • Any(unnamed)

    Any input

  • Returns:*

    The input

Passthrough for Any model from ObjectModel (Copyright © 2015 Sylvain Pollet-Villard, MIT license)

Used to define fields that can hold any type.

assertAfterCheckModelAssertion

const assertAfterCheck = require('@eluvio/elv-js-helpers/ModelAssertion/assertAfterCheck')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → (a → Boolean) → String → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • functionpreCheckFn

    The preliminary check that must pass in order for assertFn to be checked.

  • functionassertFn

    The assertion to check.

  • StringmsgStrOrFn

    An error message string or message generating function to use if assertFn returns false.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if assertFn returns true for the input OR preCheckFn returns false
  • false if assertFn returns false for the input AND preCheckFn returns true

This means that assertFn will only be called if the input first passes preCheckFn, otherwise true will always be returned (the input is ignored if it fails preCheckFn). The purpose of this is to allow prevention redundant errors, e.g. both 'expecting Number, got String "foo"' and 'Value must be an integer (got: "foo")' (by passing in a preCheckFn that returns true if input is a number - if input is not a number, then integer check is skipped)

The second element returned is a function to generate an error message. This function gets called by ObjectModel when it validates a Model and fails, passing in the assertion result (generally false), the failing value, and any attribute name(s) that were traversed to access the value.

'use strict'
const passesModelCheck = require('@eluvio/elv-js-helpers/Boolean/passesModelCheck')

const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel')

const assertAfterCheck = require('@eluvio/elv-js-helpers/ModelAssertion/assertAfterCheck')

const IntegerModel = NumberModel
  .extend()
  .assert(
    ...assertAfterCheck(
      passesModelCheck(NumberModel),
      n => Number.isInteger(n),
      'must be an integer'
    )
  )
  .as('Integer')

IntegerModel(42)        //=> 42

IntegerModel(4.2)       //=> EXCEPTION: 'Value must be an integer (got: 4.2)'

IntegerModel('foo')     //=> EXCEPTION: 'expecting Number, got String "foo"'

// Compare vs. case where assertAfterCheck is not used:

const assertionErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/assertionErrMsg')

const IntegerModelNoPrecheck = NumberModel
  .extend()
  .assert(
    n => Number.isInteger(n),
    assertionErrMsg('must be an integer')
  )
  .as('Integer')

IntegerModelNoPrecheck('foo')  //=> EXCEPTION: 'expecting Number, got String "foo"\nValue must be an integer (got: "foo")'

assertBoundedModelAssertion

const assertBounded = require('@eluvio/elv-js-helpers/ModelAssertion/assertBounded')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → a → a → Boolean → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • Modelmodel

    The Model to be bounded

  • AnylowerBound

    The lower bound that must be satisfied. If null, no lower bound will be checked.

  • AnyupperBound

    The upper bound that must be satisfied. If null, no upper bound will be checked.

  • BooleanlowerInclusive

    If true (and lowerBound is not null) then input is allowed to equal lowerBound.

  • BooleanupperInclusive

    If true (and upperBound is not null) then input is allowed to equal upperBound.

  • functioncomparatorFn

    Function used to compare the input against bound(s). Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise. This enables adding bounds to a Model type that cannot be compared using Javascript's less than (<) operator.

  • Returns:Array

    2-element array [Function, Function | String]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input satisfies the specified bound(s) OR the input is not a valid instance of the specified Model to be bounded
  • false if the input is a valid instance of the specified Model AND violates the specified bound(s)

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. 'foo' is not a Number, 'foo' must be < 1.

The second element is either an error string or a function to generate an error message. If it is a function, it will get called by ObjectModel when it validates a Model and fails, passing in the assertion result (generally false), the failing value, and any attribute name(s) that were traversed to access the value.

'use strict'
const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel')

const assertBounded = require('@eluvio/elv-js-helpers/ModelAssertion/assertBounded')

// Note use of spread operator (...) to unpack the array returned by assertBounded()
const NumberBetweenZeroAndOneModel = NumberModel.extend()
  .assert(...assertBounded(NumberModel, 0, 1, true, true))
  .as('NumberBetweenZeroAndOne')

NumberBetweenZeroAndOneModel(-1)  //=> EXCEPTION: 'Value must be >= 0 and <= 1 (got: -1)'

NumberBetweenZeroAndOneModel(0)   //=> 0

NumberBetweenZeroAndOneModel(0.5) //=> 0.5

NumberBetweenZeroAndOneModel(1)   //=> 1

NumberBetweenZeroAndOneModel(42)  //=> EXCEPTION: 'Value must be >= 0 and <= 1 (got: 42)'

assertBoundedBetweenModelAssertion

const assertBoundedBetween = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedBetween')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → a → a → Boolean → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • Modelmodel

    The Model to be bounded

  • AnylowerBound

    The lower bound that must be satisfied.

  • AnyupperBound

    The upper bound that must be satisfied.

  • BooleanlowerInclusive

    If true then input is allowed to equal lowerBound.

  • BooleanupperInclusive

    If true then input is allowed to equal upperBound.

  • functioncomparatorFn

    Function used to compare input against lowerBound and upperBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise. This enables adding bounds to a Model type that cannot be compared using Javascript's less than (<) operator.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input satisfies the specified bounds OR the input is not a valid instance of the specified Model to be bounded
  • false if the input is a valid instance of the specified Model AND violates the specified bounds.

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. 'foo' is not a Number, 'foo' must be > 0 and < 42.

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const compare = require('@eluvio/elv-js-helpers/Functional/compare')

const IntegerModel = require('@eluvio/elv-js-helpers/Model/IntegerModel')

const assertBoundedBetween = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedBetween')

// Note use of spread operator (...) to unpack the array returned by assertBoundedBetween()
const CartonEggCountModel = IntegerModel
  .extend()
  .assert(
    ...assertBoundedBetween(
      IntegerModel,
      0,
      12,
      true,
      true,
      compare
    )
  )
  .as('CartonEggCount')

CartonEggCountModel(0)       //=> 0
CartonEggCountModel(6)       //=> 6
CartonEggCountModel(12)      //=> 12
CartonEggCountModel(42)      //=> EXCEPTION: 'Value must be >= 0 and <= 12 (got: 42)'
CartonEggCountModel('foo')   //=> EXCEPTION: 'expecting Number, got String "foo"'

assertBoundedLowerModelAssertion

const assertBoundedLower = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedLower')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → a → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • Modelmodel

    The Model to be bounded

  • AnylowerBound

    The lower bound that must be satisfied.

  • Booleaninclusive

    If true (and lowerBound is not null) then input is allowed to equal lowerBound.

  • functioncomparatorFn

    Function used to compare input against lowerBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise. This enables adding bounds to a Model type that cannot be compared using Javascript's less than (<) operator.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input satisfies the specified bound OR the input is not a valid instance of the specified Model to be bounded
  • false if the input is a valid instance of the specified Model AND violates the specified bound.

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. 'foo' is not a Number, 'foo' must be > 1.

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const compare = require('@eluvio/elv-js-helpers/Functional/compare')

const IntegerModel = require('@eluvio/elv-js-helpers/Model/IntegerModel')

const assertBoundedLower = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedLower')

// Note use of spread operator (...) to unpack the array returned by assertBoundedLower()
const PositiveIntegerModel = IntegerModel
  .extend()
  .assert(
    ...assertBoundedLower(
      IntegerModel,
      0,
      false,
      compare
    )
  )
  .as('PositiveInteger')

 PositiveIntegerModel(1)       //=> 1
 PositiveIntegerModel(0)       //=> EXCEPTION: 'Value must be > 0 (got: 0)'
 PositiveIntegerModel('foo')   //=> EXCEPTION: 'expecting Number, got String "foo"'

assertBoundedUpperModelAssertion

const assertBoundedUpper = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedUpper')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → a → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • Modelmodel

    The Model to be bounded

  • AnyupperBound

    The upper bound that must be satisfied.

  • Booleaninclusive

    If true (and upperBound is not null) then input is allowed to equal upperBound.

  • functioncomparatorFn

    Function used to compare input against upperBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise. This enables adding bounds to a Model type that cannot be compared using Javascript's less than (<) operator.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input satisfies the specified bound OR the input is not a valid instance of the specified Model to be bounded
  • false if the input is a valid instance of the specified Model AND violates the specified bound.

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. 'foo' is not a Number, 'foo' must be < 42.

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const compare = require('@eluvio/elv-js-helpers/Functional/compare')

const IntegerModel = require('@eluvio/elv-js-helpers/Model/IntegerModel')

const assertBoundedUpper = require('@eluvio/elv-js-helpers/ModelAssertion/assertBoundedUpper')

// Note use of spread operator (...) to unpack the array returned by assertBoundedUpper()
const NegativeIntegerModel = IntegerModel
  .extend()
  .assert(
    ...assertBoundedUpper(
      IntegerModel,
      0,
      false,
      compare
    )
  )
  .as('NegativeInteger')

 NegativeIntegerModel(-1)      //=> -1
 NegativeIntegerModel(0)       //=> EXCEPTION: 'Value must be < 0 (got: 0)'
 NegativeIntegerModel('foo')   //=> EXCEPTION: 'expecting Number, got String "foo"'

assertEmptyModelAssertion

const assertEmpty = require('@eluvio/elv-js-helpers/ModelAssertion/assertEmpty')
() → [(* → Boolean), String]
Parameters
  • Returns:Array

    2-element array [Function, String]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input is empty
  • false if the input is NOT empty

The second element is a fixed error string to return when the input is NOT empty.

'use strict'
const isString = require('@eluvio/elv-js-helpers/Boolean/isString')

const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')

const assertAfterCheck = require('@eluvio/elv-js-helpers/ModelAssertion/assertAfterCheck')
const assertEmpty = require('@eluvio/elv-js-helpers/ModelAssertion/assertEmpty')

// Note use of spread operator (...) to unpack the arrays returned by assertAfterCheck() and assertEmpty()
const EmptyStringModel = StringModel.extend()
  .assert(
    ...assertAfterCheck(
      isString,
      ...assertEmpty
    )
  )
  .as('EmptyString')

EmptyStringModel('foo')  //=> EXCEPTION: 'Value must be empty (got: "foo")'

EmptyStringModel('')     //=> ''

EmptyStringModel([])     //=> EXCEPTION: 'expecting String, got Array []'

assertionErrMsgModelAssertion

const assertionErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/assertionErrMsg')
String → ((Boolean, *, String) → String)
Parameters
  • Stringmsg

    Error message describing the assertion condition that was not met

  • Returns:function

Returns a function to be called by ObjectModel to construct an error message when a particular assertion fails during validation.

Pass in a string describing the condition that was not met, e.g. 'must equal 42', and you will get back a function can be used to generate a full error message at runtime.

If the assertion that was passed in as the first argument to ObjectModel.assert() fails, the error message generating function will be called with the assertion result (generally false), the failing value, and any attribute name(s) that were traversed to access the value.

This allows the error message to include the attribute name (if available) and the bad value in the error message, e.g. 'Value must equal 42 (got: 43)'

'use strict'
const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel')

const assertionErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/assertionErrMsg')

const AnswerToEverythingModel = NumberModel.extend()
  .assert(
    x => x === 42,
    assertionErrMsg('must equal 42')
  )
  .as('AnswerToEverything')

AnswerToEverythingModel(43)  //=> EXCEPTION: 'Value must equal 42 (got: 43)'

assertMatchesRegexModelAssertion

const assertMatchesRegex = require('@eluvio/elv-js-helpers/ModelAssertion/assertMatchesRegex')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → RegExp → [(* → Boolean), ObjectModelErrMsgFn]
Parameters
  • Modelmodel

    The Model to add regex validation to

  • RegExpregex

    The regex that must be matched.

  • StringerrMsg

    Optional custom error message

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input matches the specified regex OR the input is not a valid instance of the specified Model to be bounded
  • false if the input is a valid instance of the specified Model AND fails to match the specified regex.

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. 42 is not a String, 42 must match regex /^[a-z]+$/.

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')

const assertMatchesRegex = require('@eluvio/elv-js-helpers/ModelAssertion/assertMatchesRegex')

// Note use of spread operator (...) to unpack the array returned by _assertBoundedUpper()
const UUIDStringModel = StringModel.extend()
  .assert(
    ...assertMatchesRegex(
      StringModel,
      /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
      'is not in UUID format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
    )
  .as('UUIDString')

UUIDStringModel('12345678-1234-1234-1234-123456789abc')  //=> '12345678-1234-1234-1234-123456789abc'

UUIDStringModel('foo')                                   //=> EXCEPTION: 'Value is not in UUID format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (got: "foo")'

UUIDStringModel(42)                                      //=> EXCEPTION: 'expecting String, got Number 42'

assertNeighborsPassModelAssertion

const assertNeighborsPass = require('@eluvio/elv-js-helpers/ModelAssertion/assertNeighborsPass')
((Boolean, *, String) → String) ObjectModelErrMsgFn => ((*, *) → Boolean) → (Function | String) → [([*] → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • functioncheckFn

    A 2-input function that returns true if the inputs are considered to be compatible, false otherwise.

  • functionerrStrOrFn

    Error message to use when ordering check fails.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element returned is a function that will take an input and return:

  • true if all neighboring elements in input return true when fed into checkFn OR the input is not array
  • false if the input is an array AND has at least one pair of neighboring elements that cause checkFn to return false.

This means that the assertion will PASS if the input is not a valid Array. The purpose of this is to prevent redundant errors, e.g. 'foo' is not an Array, 'foo' has neighbors that are not compatible.

The second element returned is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

Note that this function is equivalent to assertOrdered, but with orderingFn renamed to checkFn.

'use strict'
const assertNeighborsPass = require('@eluvio/elv-js-helpers/ModelAssertion/assertNeighborsPass')

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')
const kind = require('@eluvio/elv-js-helpers/Validation/kind')

// Note use of spread operator (...) to unpack the array returned by assertNeighborsPass()
const ArrayAllSameKindModel = defBasicModel('ArrayAllSameKindModel', Array).extend()
  .assert(
    ...assertNeighborsPass(
      (x, y) => kind(x) === kind(y),
      'elements are not all of the same kind'
    )
  )

ArrayAllSameKindModel([1, 2, 3])     //=> [1, 2, 3]

ArrayAllSameKindModel([])            //=> []

ArrayAllSameKindModel([42, 'a'])     //=> EXCEPTION: 'Value elements are not all of the same kind (got: [42,"a"])'

ArrayAllSameKindModel('foo')         //=> EXCEPTION: 'expecting Array, got String "foo"'

assertNotEmptyModelAssertion

const assertNotEmpty = require('@eluvio/elv-js-helpers/ModelAssertion/assertNotEmpty')
() → [(* → Boolean), String]
Parameters
  • Returns:Array

    2-element array [Function, String]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input is NOT empty
  • false if the input is empty

The second element is a fixed error string to return when the input is empty.

'use strict'
const isString = require('@eluvio/elv-js-helpers/Boolean/isString')

const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')

const assertAfterCheck = require('@eluvio/elv-js-helpers/ModelAssertion/assertAfterCheck')
const assertNotEmpty = require('@eluvio/elv-js-helpers/ModelAssertion/assertNotEmpty')

// Note use of spread operator (...) to unpack the arrays returned by assertAfterCheck() and assertNotEmpty()
const NonEmptyStringModel = StringModel.extend()
  .assert(
    ...assertAfterCheck(
      isString,
      ...assertNotEmpty
    )
  )
  .as('NonEmptyString')

NonEmptyStringModel('foo')  //=> 'foo'

NonEmptyStringModel('')     //=> EXCEPTION: 'Value must not be empty (got: "")'

NonEmptyStringModel([])     //=> EXCEPTION: 'expecting String, got Array []'

assertNothingModelAssertion

const assertNothing = require('@eluvio/elv-js-helpers/ModelAssertion/assertNothing')
() → [(* → Boolean), String]
Parameters
  • Returns:Array

    2-element array [Function, String]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The returned assertion will always pass, and the error message (which will never be used) is an empty string.

'use strict'
const assertNothing = require('@eluvio/elv-js-helpers/ModelAssertion/assertNothing')
const T = require('@eluvio/elv-js-helpers/Functional/T')

assertNothing()     //=> [T, '']

assertObjKeysValidModelAssertion

const assertObjKeysValid = require('@eluvio/elv-js-helpers/ModelAssertion/assertObjKeysValid')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → * → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • ModelkeyModel

    The Model to check keys against

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input is an object and all the object's keys are valid instances of the specified Model OR the input is not a Javascript object
  • false if the input IS a Javascript object AND has a key (property name) that violates specified Model

This means that the assertion will PASS if the input is not a Javascript object. The purpose of this is to prevent redundant errors, e.g. input is not an Object, property name 'foo' is invalid

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const assertObjKeysValid = require('@eluvio/elv-js-helpers/ModelAssertion/assertObjKeysValid')

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')

// Note use of spread operator (...) to unpack the array returned by assertObjKeysValid()
const NoBlankKeysObjModel = defBasicModel('NoBlankKeysObj', Object)
  .extend()
  .assert(...assertObjKeysValid(NonBlankStrModel))

NoBlankKeysObjModel({'  ': 3}) //=> EXCEPTION: 'invalid property name "  " (is not a valid NonBlankString)'

assertObjValuesValidModelAssertion

const assertObjValuesValid = require('@eluvio/elv-js-helpers/ModelAssertion/assertObjValuesValid')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → * → Boolean → [(* → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • ModelvalueModel

    The Model to check values against

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if input is an object and all the object's values are valid instances of the specified Model OR the input is not a Javascript object
  • false if the the input IS a Javascript object AND has a value that violates specified Model

This means that the assertion will PASS if the input is not a Javascript object. The purpose of this is to prevent redundant errors, e.g. input is not an Object, property name 'foo' points to a value that is invalid

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const assertObjValuesValid = require('@eluvio/elv-js-helpers/ModelAssertion/assertObjValuesValid')

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')

// Note use of spread operator (...) to unpack the array returned by assertObjValuesValid()
const NoBlankStringValsObjModel = defBasicModel('NoBlankStringValsObj', Object)
  .extend()
  .assert(...assertObjValuesValid(NonBlankStrModel))

NoBlankStringValsObjModel({foo: '  '}) //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: Value must not be a blank string (got: "  "))'

assertOrderedModelAssertion

const assertOrdered = require('@eluvio/elv-js-helpers/ModelAssertion/assertOrdered')
((Boolean, *, String) → String) ObjectModelErrMsgFn => ((*, *) → Boolean) → (Function | String) → [([*] → Boolean), ObjectModelErrMsgFn | String]
Parameters
  • functionorderingFn

    A 2-input function that returns true if the inputs are considered to be in order, false otherwise. Note that this function could check for ascending or descending order, and allow or disallow duplicates. It could also check for any arbitrary pair-wise condition to be considered 'ordered', but the most common case is checking whether an array is sorted or not.

  • functionerrStrOrFn

    Error message to use when ordering check fails.

  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element returned is a function that will take an input and return:

  • true if the input is ordered OR the input is not array
  • false if the input is an array AND is not ordered.

This means that the assertion will PASS if the input is not a valid array. The purpose of this is to prevent redundant errors, e.g. 'foo' is not an Array, 'foo' is not sorted.

The second element returned is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

Whether the array is ordered or not is determined by orderingFn, a function that takes two inputs and returns true if the inputs are in order or false otherwise.

Note that this function is equivalent to assertNeighborsPass, but with checkFn renamed to orderingFn.

'use strict'
const assertOrdered = require('@eluvio/elv-js-helpers/ModelAssertion/assertOrdered')

const defArrayModel = require('@eluvio/elv-js-helpers/ModelFactory/defArrayModel')

// Note use of spread operator (...) to unpack the array returned by assertOrdered()
const OrderedNumArrayModel = defArrayModel('OrderedArray', Number).extend()
  .assert(
    ...assertOrdered(
      (x, y) => x <= y,
      'is not in ascending order'
    )
  ).as('OrderedNumArray')

OrderedNumArrayModel([1, 2, 3])     //=> [1, 2, 3]

OrderedNumArrayModel([])            //=> []

OrderedNumArrayModel([3, 2])        //=> EXCEPTION: 'Value is not in ascending order (got: [3,2])'

OrderedNumArrayModel('foo')         //=> EXCEPTION: 'expecting Array of Number, got String "foo"'

assertPropRelModelAssertion

const assertPropRel = require('@eluvio/elv-js-helpers/ModelAssertion/assertPropRel')
((Boolean, *, String) → String) ObjectModelErrMsgFn => Model → ((b, a) → Boolean) → String → String → String → [(* → Boolean), ObjectModelErrMsgFn | String]
λcurried function
Parameters
  • functioncheckFn

    A 2-input function taking value of object's propertyName2 FIRST, then object's propertyName1 SECOND (this is to allow more intuitive use with the way isGT / isGTE etc are curried)

  • StringreqDesc

    Description of required relation, e.g. 'must be greater than' - this will be used in error messages e.g. 'propertyName1 must be greater than propertyName2'

  • StringpropertyName1

    Name of attribute to check against propertyName2

  • StringpropertyName2

    Name of attribute to check against propertyName1

  • Returns:Array

    2-element array [Function, Function | String]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input satisfies the specified property relationship OR the input is not an object
  • false if the input is an object AND violates the specified property relationship

This means that the assertion will PASS if the input is not a valid instance of the Model to be bounded. The purpose of this is to prevent redundant errors, e.g. Value is not an Object, 'foo' must be greater than 'bar'.

The second element is either an error string or a function to generate an error message. If it is a function, it will get called by ObjectModel when it validates a Model and fails, passing in the assertion result (generally false), the failing value, and any attribute name(s) that were traversed to access the value.

'use strict'
const assertPropRel = require('@eluvio/elv-js-helpers/ModelAssertion/assertPropRel')

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')
const isGTE = require('@eluvio/elv-js-helpers/Boolean/isGTE')

const NumLimitsModel = defObjectModel(
  'NumberLimits',
  {
    min: Number,
    max: Number
  }
).extend().assert(
  ...assertPropRel(
    isGTE,
    'must be greater than or equal to',
    'max',
    'min'
  )
)

NumLimitsModel({min:1, max:2})  //=> {min:1, max:2}

NumLimitsModel({min:2, max:1})  //=> EXCEPTION: 'max (1) must be greater than or equal to min (2)'

assertValidUTCStrModelAssertion

const assertValidUTCStr = require('@eluvio/elv-js-helpers/ModelAssertion/assertValidUTCStr')
((Boolean, *, String) → String) ObjectModelErrMsgFn => () → [(* → Boolean), ObjectModelErrMsgFn]
Parameters
  • Returns:Array

    2-element array [Function, Function]. See description for details.

Returns a 2-element array for use in an ObjectModel assertion

The first element is a function that will take an input and return:

  • true if the input can be parsed as UTC datetime string (yyyy:MM:ddThh:mm:ssZ) OR the input is not a valid instance of NonBlankStrModel
  • false if the input is a valid instance of NonBlankStrModel AND fails to parse as a UTC datetime string.

This means that the assertion will PASS if the input is not a valid NonBlankString. The purpose of this is to prevent redundant errors, e.g. 42 is not a String, 42 is not a valid ISO 8601 datetime string.

The second element is a function to be called by ObjectModel to construct an error message if the bounds validation fails.

'use strict'
const assertValidUTCStr = require('@eluvio/elv-js-helpers/ModelAssertion/assertValidUTCStr')

const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')

// Note use of spread operator (...) to unpack the array returned by _assertBoundedUpper()
const UTCDateTimeStringModel = StringModel.extend()
  .assert(...assertValidUTCStr())
  .as('UTCDateTimeString')

UTCDateTimeStringModel('2022-05-03T00:26:07Z')    //=> '2022-05-03T00:26:07Z'

UTCDateTimeStringModel('2022-99-03T00:26:07Z')    //=> EXCEPTION: 'Value is not a valid UTC datetime string (got: "2022-99-03T00:26:07Z")'

UTCDateTimeStringModel('foo')                     //=> EXCEPTION: 'Value is not a valid UTC datetime string (got: "foo")'

assocComputedFunctional

const assocComputed = require('@eluvio/elv-js-helpers/Functional/assocComputed')
String → Function → Object → Object
λcurried function
Parameters
  • Stringprop

    The name of the property to set

  • functioncomputeFn

    The function to use to compute value of prop

  • Objectobj

    The object to copy and use as input to computeFn

  • Returns:Object

Returns a shallow copy of object with a specified property set to computeFn(obj)

Note that if obj is an ObjectModel instance the return value will be a plain Javascript object without model constraints.

'use strict'
const assocComputed = require('@eluvio/elv-js-helpers/Functional/assocComputed')

assocComputed('bar', x => x.foo * 2, {foo: 2}) //=> {foo: 2, bar: 4}

// function is curried: call with fewer than 3 args to obtain a narrower function
const addTax = assocComputed('tax', x => x.price * 0.05)

addTax({product: 'towel', price: 1})     //=> {product: 'towel', price: 1, tax: 0.05}

AsyncADT

const Async = require('@eluvio/elv-js-helpers/ADT/Async')
((e → (), a → ()) → ()) → Async e a
((e → (), a → ()) → (() → ()) → Async e a
Parameters
  • function(unnamed)

    A binary function that accepts 2 unary functions, and may return a function - if it returns a function, this will be called if the Async is cancelled. The Async will call the binary function, feeding in a reject function and a resolve function, to be called to signal completion of task.

  • Returns:Async

Passthrough for the Async Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to create Async objects without adding the Crocks package as a dependency.

const Async = require('@eluvio/elv-js-helpers/ADT/Async')

base58DecodeConversion

const base58Decode = require('@eluvio/elv-js-helpers/Conversion/base58Decode')
String → Uint8Array
Parameters
  • Stringstr

    The base-58 string to decode

  • Returns:Uint8Array

    The decoded bytes

Passthrough for the decode() function from the bs58 npm package. (Copyright © 2018 cryptocoinjs, MIT License)

Decodes a base-58 string to a Uint8Array of the original bytes.

Throws an exception on bad input.

'use strict'
const base58Decode = require('@eluvio/elv-js-helpers/Conversion/base58Decode')

const bytes = base58Decode('2PDzvA279deFCZe2SV1B6NQQkDE')
const hexString = Buffer.from(bytes).toString('hex')
console.log(hexString)                                   //=> OUTPUT: '01b6368fd21198ff5f97b00dc3918d6215bca039'

base58EncodeConversion

const base58Encode = require('@eluvio/elv-js-helpers/Conversion/base58Encode')
String → Uint8Array
Parameters
  • Uint8Arraybytes

    The bytes to encode

  • Returns:String

    The base-58 string

Passthrough for the encode() function from the bs58 npm package. (Copyright © 2018 cryptocoinjs, MIT License)

Encodes a Uint8Array, Buffer, or Array of bytes as a Base58 string.

Throws an exception on bad input.

'use strict'
const base58Encode = require('@eluvio/elv-js-helpers/Conversion/base58Encode')

const bytes = Uint8Array.from([
 0, 60,  23, 110, 101, 155, 234,
 15, 41, 163, 233, 191, 120, 128,
 193, 18, 177, 179,  27,  77, 200,
 38, 38, 129, 135
])
base58Encode(bytes)                   //=> '16UjcYNBG9GTK4uq2f7yYEbuifqCzoLMGS'

const hexString = '5b4b3f4c262aa0f5237cb9a4b59ab0825ddead28'
const hexBytes = Uint8Array.from(Buffer.from(hexString, 'hex'));

base58Encode(hexBytes)                //=> '2GmbemxTtSdy1YeFWE6zg6CmG8wy'

Base58StrModelModel

const Base58StrModel = require('@eluvio/elv-js-helpers/Model/Base58StrModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is a non-blank Base58-encoded string.

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const Base58StrModel = require('@eluvio/elv-js-helpers/Model/Base58StrModel')

Base58StrModel('foo') //=> 'foo'

Base58StrModel('FOO') //=> EXCEPTION: 'Value is not a valid Base58 string (got: "FOO")'

Base58StrModel('  ')  //=> EXCEPTION: 'Value must not be a blank string (got: "  ")'

Base58StrModel(42)    //=> EXCEPTION: 'expecting String, got Number 42'

boolsToIntConversion

const boolsToInt = require('@eluvio/elv-js-helpers/Conversion/boolsToInt')
[Boolean] → Integer
Parameters
  • Array.<Boolean>boolArray

    An array of booleans representing binary digits of a non-negative integer (most significant bit first)

  • Returns:Integer

Converts an array of booleans to a number by interpreting them as binary digits (most significant bits first)

'use strict'
const boolsToInt = require('@eluvio/elv-js-helpers/Conversion/boolsToInt')

boolsToInt([false, false, true]) //=> 1

boolsToInt([true, false])        //=> 2

boolsToInt([true, true, true])   //=> 7

callerFuncNameMisc

const callerFuncName = require('@eluvio/elv-js-helpers/Misc/callerFuncName')
() → String

Returns the name of the (non-node-module) function that was responsible for current function getting called ( 'current function' meaning the one containing the callerFuncName() call).

'use strict'
const currentFuncName = require('@eluvio/elv-js-helpers/Misc/currentFuncName')
const callerFuncName = require('@eluvio/elv-js-helpers/Misc/callerFuncName')

const MyFunc = () => console.log('Function: ' + currentFuncName() + ' was called by: ' + callerFuncName())

const OuterFunc = () => MyFunc()

OuterFunc()  //=> OUTPUT: 'Function: MyFunc was called by: OuterFunc'

chainFunctional

const chain = require('@eluvio/elv-js-helpers/Functional/chain')
(a → m b) → m a → m b
λcurried function
Parameters
  • function(unnamed)

    A curried function that takes a 'normal' value and returns a wrapped value)

  • Object(unnamed)

    Instance of Functional data type to pass into function

  • Returns:*

    The wrapped result

Passthrough for the chain() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Provides a pointfree way to call .chain() on a value wrapped in a Functional data type.

Given a curried function that takes a 'normal' value and returns a wrapped value, chain will convert it into a function that takes a wrapped value. The returned value will not gain an extra layer of wrapping from the input.

'use strict'
const chain = require('@eluvio/elv-js-helpers/Functional/chain')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const map = require('@eluvio/elv-js-helpers/Functional/map')

// function has only one input, not need to curry
const reciprocal = a => a === 0 ? Err(['division by zero']) : Ok(1/a)

const ok4 = Ok(4)
const ok0 = Ok(0)
const badNum = Err(['failed to read input'])

reciprocal(4).inspect()              //=> 'Ok 0.25'

reciprocal(0).inspect()              //=> 'Err [ "division by zero" ]'

// passing in a wrapped value results in NaN (reciprocal does not know to unwrap value before use)
reciprocal(ok4).inspect()            //=> 'Ok NaN'

// chain() asks input wrapper to remove wrapping and pass value to function, then does not re-wrap the (wrapped) return value
chain(reciprocal, ok4).inspect()     //=> 'Ok 0.25'

// reciprocal gets value 0 and returns Err
chain(reciprocal, ok0).inspect()     //=> 'Err [ "division by zero" ]'

// badNum ignores request to apply reciprocal()
chain(reciprocal, badNum).inspect()  //=> 'Err [ "failed to read input" ]'

// compare to map - (which does not specify that result should not be re-wrapped)
// return value is wrapped twice, once by reciprocal and once by ok4
map(reciprocal, ok4).inspect()       //=> 'Ok Ok 0.25'

// chain is curried, it is possible to call with only the first argument to return a new function
const wrappedReciprocal = chain(reciprocal)

wrappedReciprocal(ok4).inspect()     //=> 'Ok 0.25'

cloneFunctional

const clone = require('@eluvio/elv-js-helpers/Functional/clone')
* → *
Parameters
  • Objectx

    the item to clone

  • Returns:Object

Modified version of Ramda's clone function (Copyright © Scott Sauyet and Michael Hurley)

Uses original item's constructor function when input is an object.

Used to preserve ObjectModel constraints.

'use strict'
const clone = require('@eluvio/elv-js-helpers/Functional/clone')

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')

const PersonNameModel = defObjectModel('PersonName', {first: String, last: String})

const arthur = PersonNameModel({first: 'Arthur', last:'Dent'})

const arthurClone = clone(arthur)

arthurClone.last = 'Clone'

console.log(arthurClone.last)       //=> OUTPUT: 'Clone'

console.log(arthur.last)            //=> OUTPUT: 'Dent'

arthurClone.last = 3                //=> EXCEPTION: 'expecting last to be String, got Number 3'

cmpIndexableFunctional

const cmpIndexable = require('@eluvio/elv-js-helpers/Functional/cmpIndexable')
[a] → [b] → -1 | 0 | 1
λcurried function
Parameters
  • Arrayx

    A string or an array whose elements can be compared with <

  • Arrayy

    A string or an array whose elements can be compared with <

  • Returns:Integer

    -1 | 0 | 1

Compares two indexable items (generally arrays or strings) x and y pairwise and returns:

  • -1 if x can be considered 'less than' y (either x[i] < y[i] or y[i] is undefined for first pair x[i],y[i] where x[i] !== y[i])
  • 0 if x can be considered 'equal to' y (more specifically, if neither x < y nor y < x are true)
  • 1 if y can be considered 'less than' x (either y[i] < x[i] or x[i] is undefined for first pair x[i],y[i] where x[i] !== y[i])

Used as an input into sorting and validation functions.

Throws an exception on bad inputs.

'use strict'
const cmpIndexable = require('@eluvio/elv-js-helpers/Functional/cmpIndexable')

cmpIndexable([], [42])         //=> -1

cmpIndexable([42], [])         //=> 1

cmpIndexable([42], [42])       //=> 0

cmpIndexable([42, 1], [42])    //=> 1

cmpIndexable(2, 1)             //=> EXCEPTION: 'cmpIndexable: first argument does not have a length'

cmpIndexable('abc', 'ab')      //=> 1

cmpIndexable(null, undefined)  //=> EXCEPTION: "Cannot read properties of null (reading 'length')"

cmpIndexable([42], ['a'])      //=> EXCEPTION: 'cmpIndexable: elements at index 0 are not comparable'

comparatorFunctional

const comparator = require('@eluvio/elv-js-helpers/Functional/comparator')
(a → a → Boolean) → (a → b → -1 | 0 | 1)
Parameters
  • functionfn

    the 2-input function (returning Boolean) to use for testing inputs

  • Returns:function
    • a 2-input comparator function that returns -1, 0, or 1

Copies name and functionality of Ramda's comparator function (Copyright © Scott Sauyet and Michael Hurley)

When supplied with a boolean 2-input function f, will return another 2-input function that returns:

-1 if f(a, b) is true 1 if f(b, a) is true 0 otherwise

This function can be passed in as a compare function to e.g. Javascript's Array.sort() method.

'use strict'
const comparator = require('@eluvio/elv-js-helpers/Functional/comparator')

const isLT = require('@eluvio/elv-js-helpers/Boolean/isLT')
const isGT = require('@eluvio/elv-js-helpers/Boolean/isGT')

const compAscending = comparator(isGT)
const compDescending = comparator(isLT)

let data = [1, 42, -42, 0]

data.sort(compAscending)
console.log(data)             //=> OUTPUT: [-42, 0, 1, 42]

data.sort(compDescending)
console.log(data)             //=> OUTPUT: [42, 1, 0, -42]

compareFunctional

const compare = require('@eluvio/elv-js-helpers/Functional/compare')
a → b → -1 | 0 | 1
λcurried function
Parameters
  • Anyx

    A value that can be compared with <

  • Anyy

    A value that can be compared with <

  • Returns:Integer

    -1 | 0 | 1

Compares two items x and y using Javascript's less than (<) operator, and returns:

  • -1 if x < y
  • 1 if y < x
  • 0 otherwise (x and y may not be equal, e.g. null < undefined and undefined < null are both false)

Used as an input into sorting and validation functions.

'use strict'
const compare = require('@eluvio/elv-js-helpers/Functional/compare')

compare(1, 2)            //=> -1

compare(2, 2)            //=> 0

compare(2, 1)            //=> 1

compare('a', 'b')        //=> -1

compare(null, undefined) //=> 0

compare(undefined, null) //=> 0

compare([1], 'a')        //= -1

compareFracStrFunctional

const compareFracStr = require('@eluvio/elv-js-helpers/Functional/compareFracStr')
a → b → -1 | 0 | 1
λcurried function
Parameters
  • Stringstr1

    A string representing a fraction or whole number

  • Stringstr2

    A string representing a fraction or whole number

  • Returns:Integer

    -1 | 0 | 1

Compares two strings x and y using fraction.js and returns:

  • -1 if x < y
  • 0 if x == y (more specifically, if neither x < y nor y < x are true)
  • 1 if y < x

Used as an input into sorting and validation functions.

'use strict'
const compareFracStr = require('@eluvio/elv-js-helpers/Functional/compareFracStr')

compareFracStr('1', '2')        //=> -1

compareFracStr('1/2', '1/4')    //=> 1

compareFracStr(2, 1)            //=> EXCEPTION: 'expecting String, got Number 2'

compareFracStr('a', 'b')        //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "a")'

compareFracStr(null, undefined) //=> EXCEPTION: 'expecting String, got null'

compareFracStr(0.5, '1/2')      //=> EXCEPTION: 'expecting String, got Number 0.5'

conditionalCheckBoolean

const conditionalCheck = require('@eluvio/elv-js-helpers/Boolean/conditionalCheck')
(* → Boolean) → (* → Boolean) → (* → Boolean)
Parameters
  • functionpreCheckFn

    A 1-input function - the precondition for checkFn to take place

  • functioncheckFn

    A 1-input function - the actual check to perform

  • Returns:function

Creates a function that:

  • Returns true if preCheckFn is false or checkFn is true.
  • Returns false if preCheckFn is true and checkFn is false

The effect is that checkFn is only performed if preCheckFn is true.

If preCheckFn is false, checking is short-circuited and true is returned.

Generally used to skip irrelevant checks and avoid redundant errors in assertions, e.g. 'foo' is not a number + 'foo' must be > 0

'use strict'
const conditionalCheck = require('@eluvio/elv-js-helpers/Boolean/conditionalCheck')

const isString = require('@eluvio/elv-js-helpers/Boolean/isString')

const stringStartsWithF = conditionalCheck(isString, x => x.startsWith('f'))

// Skip assertion, value is not a string:
stringStartsWithF(1)        //=> true

stringStartsWithF('foo')    //=> true

stringStartsWithF('bar')    //=> false

constantFunctional

const constant = require('@eluvio/elv-js-helpers/Functional/constant')
a → (() → a)
Parameters
  • Any(unnamed)

    The value to always return

  • Returns:function

    Function that ignores any input and always returns the original value

Passthrough for the constant() Crocks combinator (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/combinators.html#constant for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given an input, returns a function that always returns that input.

'use strict'
const constant = require('@eluvio/elv-js-helpers/Functional/constant')

const always42 = constant(42)

always42()   //=> 42

currentFuncNameMisc

const currentFuncName = require('@eluvio/elv-js-helpers/Misc/currentFuncName')
() → String

Returns name of function that it is called from. Used for introspection/logging

'use strict'
const currentFuncName = require('@eluvio/elv-js-helpers/Misc/currentFuncName')

const MyFunc = () => console.log('Entered function: ' + currentFuncName())

MyFunc()  //=> OUTPUT: 'Entered function: MyFunc'

curryFunctional

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
((a, b, …) → z) → a → b → … → z
Parameters
  • function(unnamed)

    The function to curry

  • Returns:function

    The curried function

Passthrough for the curry() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/helpers.html#curry for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Currying converts a function that takes multiple arguments into one that can take fewer arguments and returns a function that can be supplied with the remaining arguments. This can be useful for creating a more specific function from a general function.

It is similar to defining a function using syntax like const mult = x => y => x * y, but allows calling the function with the full list of arguments if desired (calling mult(2, 2) does not work when using the x => y => syntax).

Some functions like liftA2 and liftA2Join require a curried function as input.

'use strict'
const curry = require('@eluvio/elv-js-helpers/Functional/curry')

const withinBounds = (lower, upper, val) => (val >= lower) && (val <= upper)

// curry an already-defined function
const fromZeroToOne = curry(withinBounds)(0, 1) // returns a new function that takes 1 argument (val)

fromZeroToOne(0)                                //=> true

fromZeroToOne(42)                               //=> false

// curry the function during definition
const greaterThan = curry(
  (lowerBound, val) => (val > lowerBound)
)

// function can be called normally with full set of arguments
greaterThan(0, 1)                               //=> true

// when called with only lowerBound, returns a new function that takes 1 argument (val)
const isPositive = greaterThan(0)

isPositive(0)                                   //=> false

isPositive(42)                                  //=> true

DatetimeModelModel

const DatetimeModel = require('@eluvio/elv-js-helpers/Model/DatetimeModel')
* → Date | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Date

    The validated input

An ObjectModel which validates that an input is a Javascript Date

If input passes validation, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const DatetimeModel = require('@eluvio/elv-js-helpers/Model/DatetimeModel')

// when validation succeeds, returns the input:
const testVal = new Date('2022-01-01T07:30:00Z')
const myDatetime = DatetimeModel(testVal)
myDatetime.valueOf()                             //=> 1641022200000

DatetimeModel('foo')                             //=> EXCEPTION: 'expecting Date, got String "foo"'

defArrayModelModelFactory

const defArrayModel = require('@eluvio/elv-js-helpers/ModelFactory/defArrayModel')
String → ([Model] | Model) → (* → Array | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • Array.<Model>def

    The type/Model or array of types/Model that are valid for elements

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Passthrough for ArrayModel() function from ObjectModel (Copyright © 2015 Sylvain Pollet-Villard, MIT license) with name assignment added.

Returns an ObjectModel which will validate that an input is:

  • A Javascript Array
  • Made up of elements that are of the specified type definition(s)

To define an array that can hold any type of value, pass in AnyModel for def.

'use strict'
const NonNegativeNumModel = require('@eluvio/elv-js-helpers/Model/NonNegativeNumModel')

const defArrayModel = require('@eluvio/elv-js-helpers/ModelFactory/defArrayModel')

const AgeArrayModel = defArrayModel('AgeArray', NonNegativeNumModel)

AgeArrayModel([42])        //=> [42]

AgeArrayModel([])          //=> []

AgeArrayModel(-1)          //=> EXCEPTION: 'expecting Array of NonNegativeNumber, got Number -1'

AgeArrayModel([-1])        //=> EXCEPTION: 'Array[0] must be >= 0 (got: -1)'

AgeArrayModel('foo')       //=> EXCEPTION: 'expecting Array of NonNegativeNumber, got String "foo"'

AgeArrayModel(['foo'])     //=> EXCEPTION: 'expecting Array[0] to be Number, got String "foo"'

defBasicModelModelFactory

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')
String → ([Model] | Model) → (* → Array | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • Array.<Model>def

    The type/Model or array of types/Model that are valid for input

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Passthrough for BasicModel() function from ObjectModel (Copyright © 2015 Sylvain Pollet-Villard, MIT license) with name assignment added.

Returns an ObjectModel which will validate that an input is of the specified type(s)

'use strict'
const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')

const StringModel = defBasicModel('String', String)

StringModel(42)      //=> EXCEPTION: 'expecting String, got Number 42'
StringModel('foo')   //=> 'foo'

defBoundedFracStrModelModelFactory

const defBoundedFracStrModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedFracStrModel')
String → (Number | null) → (Number | null) → (Boolean | null) → (Boolean | null) → (* → Model | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • StringlowerBound

    The lower bound (a string that is a valid FracStringModel) that must be satisfied. If null, no lower bound will be checked.

  • StringupperBound

    The upper bound (a string that is a valid FracStringModel) that must be satisfied. If null, no upper bound will be checked.

  • BooleanlowerInclusive

    If true (and lowerBound is not null) then input is allowed to equal lowerBound.

  • BooleanupperInclusive

    If true (and upperBound is not null) then input is allowed to equal upperBound.

  • Returns:Model

Returns an ObjectModel which will validate that an input is:

  • A Javascript String
  • In the form of a whole number or fraction 'x', '-x', 'x/y' or '-x/y', y !=0
  • Greater than a specified lower bound (if specified) or equal to the lower bound (if lower inclusivity is specified)
  • Less than a specified upper bound (if specified) or equal to the upper bound (if upper inclusivity is specified)

Note that it is possible to specify no bounds at all, in which case the returned Model will only check that input is a string representing a whole number or fraction.

Also note that bounds must be strings, e.g. '0', '22/7', '-42'.

'use strict'
const defBoundedFracStrModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedFracStrModel')

const PositiveFracModel = defBoundedFracStrModel(
  'PositiveFraction',
  '0',
  null,
  false,
  null
)

PositiveFracModel('42')       //=> '42'

PositiveFracModel('22/7')     //=> '22/7'

PositiveFracModel('0')        //=> EXCEPTION: 'Value must be > 0 (got: "0")'

PositiveFracModel('-42')      //=> EXCEPTION: 'Value must be > 0 (got: "-42")'

PositiveFracModel('foo')      //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "foo")'

PositiveFracModel(42)         //=> EXCEPTION: 'expecting String, got Number 42'

const NegativeFracModel = defBoundedFracStrModel(
  'NegativeFraction',
  null,
  '0',
  null,
  false
)

NegativeFracModel('42')       //=> EXCEPTION: 'Value must be < 0 (got: "42")'

NegativeFracModel('0')        //=> EXCEPTION: 'Value must be < 0 (got: "0")'

NegativeFracModel('-22/7')    //=> '-22/7'

NegativeFracModel('-42')      //=> '-42'

const FracZeroToOneModel = defBoundedFracStrModel(
  'FractionZeroToOne',
  '0',
  '1',
  true,
  true
)

FracZeroToOneModel('1/2')     //=> '1/2'

defBoundedIntModelModelFactory

const defBoundedIntModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedIntModel')
String → (Number | null) → (Number | null) → (Boolean | null) → (Boolean | null) → (* → Integer | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • NumberlowerBound

    The lower bound that must be satisfied. If null, no lower bound will be checked.

  • NumberupperBound

    The upper bound that must be satisfied. If null, no upper bound will be checked.

  • BooleanlowerInclusive

    If true (and lowerBound is not null) then input is allowed to equal lowerBound.

  • BooleanupperInclusive

    If true (and upperBound is not null) then input is allowed to equal upperBound.

  • Returns:function

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

  • A Javascript Number
  • An integer
  • Greater than a specified lower bound (if specified) or equal to the lower bound (if lower inclusivity is specified)
  • Less than a specified upper bound (if specified) or equal to the upper bound (if upper inclusivity is specified)

Note that it is possible to specify no bounds at all, in which case the returned Model will only check that input is an integer.

'use strict'
const defBoundedIntModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedIntModel')

const CartonEggCountModel = defBoundedIntModel('CartonEggCount', 0, 12, true, true)

CartonEggCountModel(-1)     //=> EXCEPTION: 'Value must be >= 0 and <= 12 (got: -1)'

CartonEggCountModel(0)      //=> 0

CartonEggCountModel(4.2)    //=> EXCEPTION: 'Value must be an integer (got: 4.2)'

CartonEggCountModel(6)      //=> 6

CartonEggCountModel(42)     //=> EXCEPTION: 'Value must be >= 0 and <= 12 (got: 42)'

CartonEggCountModel('foo')  //=> EXCEPTION: 'expecting Number, got String "foo"'

defBoundedNumModelModelFactory

const defBoundedNumModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedNumModel')
String → (Number | null) → (Number | null) → (Boolean | null) → (Boolean | null) → (* → Model | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • NumberlowerBound

    The lower bound that must be satisfied. If null, no lower bound will be checked.

  • NumberupperBound

    The upper bound that must be satisfied. If null, no upper bound will be checked.

  • BooleanlowerInclusive

    If true (and lowerBound is not null) then input is allowed to equal lowerBound.

  • BooleanupperInclusive

    If true (and upperBound is not null) then input is allowed to equal upperBound.

  • Returns:Model

Returns an ObjectModel which will validate that an input is:

  • A Javascript Number
  • Greater than a specified lower bound (if specified) or equal to the lower bound (if lower inclusivity is specified)
  • Less than a specified upper bound (if specified) or equal to the upper bound (if upper inclusivity is specified)

Note that it is possible to specify no bounds at all, in which case the returned Model will only check that input is a number.

'use strict'
const defBoundedNumModel = require('@eluvio/elv-js-helpers/ModelFactory/defBoundedNumModel')

const HumanHeightMetersModel = defBoundedNumModel('HumanHeightMeters', 0, 3, false, true)

HumanHeightMetersModel(0)     //=> EXCEPTION: 'Value must be > 0 and <= 3 (got: 0)'

HumanHeightMetersModel(1.5)   //=> 1.5

HumanHeightMetersModel(4)     //=> EXCEPTION: 'Value must be > 0 and <= 3 (got: 4)'

HumanHeightMetersModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

defNonEmptyArrModelModelFactory

const defNonEmptyArrModel = require('@eluvio/elv-js-helpers/ModelFactory/defNonEmptyArrModel')
String → ([Model] | Model) → (* → Array | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • Array.<Model>def

    The type/Model or array of types/Model that elements

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

  • A Javascript Array
  • Made up of elements that are of the specified type definition(s)

To define an array that can hold any type of value, pass in AnyModel for def.

'use strict'
const defNonEmptyArrModel = require('@eluvio/elv-js-helpers/ModelFactory/defNonEmptyArrModel')

const NonNegativeNumModel = require('@eluvio/elv-js-helpers/Model/NonNegativeNumModel')

const NonEmptyAgeArrayModel = defNonEmptyArrModel('NonEmptyAgeArray', NonNegativeNumModel)

NonEmptyAgeArrayModel([42])        //=> [42]

NonEmptyAgeArrayModel([])          //=> EXCEPTION: 'Value must not be empty (got: [])'

NonEmptyAgeArrayModel(-1)          //=> EXCEPTION: 'expecting Array of NonNegativeNumber, got Number -1'

NonEmptyAgeArrayModel([-1])        //=> EXCEPTION: 'Array[0] must be >= 0 (got: -1)'

NonEmptyAgeArrayModel('')          //=> EXCEPTION: 'expecting Array of NonNegativeNumber, got String ""'

NonEmptyAgeArrayModel(['foo'])     //=> EXCEPTION: 'expecting Array[0] to be Number, got String "foo"'

defNonEmptyTypedKVObjModelModelFactory

const defNonEmptyTypedKVObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defNonEmptyTypedKVObjModel')
String → Model → Model → (* → Object | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • ModelkeyModel

    The Model to validate keys against

  • ModelvalueModel

    The Model to validate values against

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

  • A Javascript Object
  • Has keys that validate against a Model
  • Has values that validate against a Model
  • Has at least one key

See also defTypedKVObjModel

'use strict'
const defNonEmptyTypedKVObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defNonEmptyTypedKVObjModel')

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const NonEmptyNonBlankKVModel = defNonEmptyTypedKVObjModel(
  'NonEmptyNonBlankKV',
  NonBlankStrModel,
  NonBlankStrModel
)

NonEmptyNonBlankKVModel({})               //=> EXCEPTION: 'Value must have at least one entry (got: {})'

NonEmptyNonBlankKVModel({foo: 'bar'})     //=> {foo: 'bar'}

NonEmptyNonBlankKVModel({foo: ' '})       //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: Value must not be a blank string (got: " "))'

NonEmptyNonBlankKVModel({' ': 'bar'})     //=> EXCEPTION: 'invalid property name " " (is not a valid NonBlankString)'

NonEmptyNonBlankKVModel({foo: 42})        //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: expecting String, got Number 42)'

NonEmptyNonBlankKVModel(42)               //=> EXCEPTION: 'expecting Object, got Number 42'

// When used for a field in an object, the error message will include the name of the field:

const MediaFileModel = defObjectModel(
  "MediaFile",
  {
    streams: defNonEmptyTypedKVObjModel(
      "streamsMap",
      NonBlankStrModel,
      defObjectModel(
        "stream",
        {
          type: ["audio", "subtitle", "video"]
        }
      )
    )
  }
)

MediaFileModel({streams: {}})             //=> EXCEPTION: 'streams must have at least one entry (got: {})'

defObjectModelModelFactory

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')
String → Object → (* → Object | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • Objectdef

    The definition (field structure) of the Model to generate

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Passthrough for ObjectModel() function from ObjectModel (Copyright © 2015 Sylvain Pollet-Villard, MIT license) with name assignment added

Returns an ObjectModel which will validate that an input is:

Extra (i.e. unrecognized) fields are allowed. Use defSealedObjModel() instead if you wish to disallow.

'use strict'
const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')

const PersonNameModel = defObjectModel('PersonName', {first: String, last: String})

PersonNameModel(-1)                                        //=> EXCEPTION: 'expecting Object, got Number -1'

PersonNameModel({first: 'Arthur', last: 'Dent'})           //=> {"first":"Arthur","last":"Dent"}

PersonNameModel({first: 'Arthur'})                         //=> EXCEPTION: 'expecting last to be String, got undefined'

PersonNameModel({first: 'A', last: 'D', species: 'human'}) //=> {first: 'A', last: 'D', species: 'human'}

defRegexMatchedStrModelModelFactory

const defRegexMatchedStrModel = require('@eluvio/elv-js-helpers/ModelFactory/defRegexMatchedStrModel')
(String, RexExp, String | undefined) → (* → String | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • RegExpregex

    The regex that must be matched

  • StringerrMsg

    Optional custom error message string (if omitted, regex will be included as part of standard error message)

  • Returns:function

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

'use strict'
const defRegexMatchedStrModel = require('@eluvio/elv-js-helpers/ModelFactory/defRegexMatchedStrModel')

const UUIDStringModel = defRegexMatchedStrModel('UUIDString', /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/)

UUIDStringModel('12345678-90ab-cdef-0123-4567890abcde')  //=> '12345678-90ab-cdef-0123-4567890abcde'

UUIDStringModel('foo')                                   //=> EXCEPTION: 'Value is not in valid format or contains illegal characters (must match regular expression: /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/) (got: "foo")'

UUIDStringModel(42)                                      //=> EXCEPTION: 'expecting String, got Number 42'

// supply a nicer error message
const UUIDStringModel2 = defRegexMatchedStrModel(
   'UUIDString',
   /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,
   'is not in UUID format "xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"'
 )

UUIDStringModel2('foo')  //=> EXCEPTION: 'Value is not in UUID format "xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" (got: "foo")'

defSealedObjModelModelFactory

const defSealedObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defSealedObjModel')
String → Object → (* → Object | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • Objectdef

    The definition (field structure) of the Model to generate

  • Returns:function

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

  • A Javascript Object
  • Satisfies the specified field definitions
  • Contains no extra fields

The object returned by the function will also throw an exception if you attempt to add a field to it that is not in the original definition.

NOTE: Copying the object using a function like Ramda's assoc function will not preserve this protection for the copy.

'use strict'
const defSealedObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defSealedObjModel')

const PersonNameModel = defSealedObjModel('PersonName', {first: String, last: String})

PersonNameModel(-1)                                        //=> EXCEPTION: 'expecting Object, got Number -1'

PersonNameModel({first: 'Arthur', last: 'Dent'})           //=> {"first":"Arthur","last":"Dent"}

PersonNameModel({first: 'Arthur'})                         //=> EXCEPTION: 'expecting last to be String, got undefined'

PersonNameModel({first: 'A', last: 'D', species: 'human'}) //=> EXCEPTION: 'Unrecognized property name(s): species'

defTypedKVObjModelModelFactory

const defTypedKVObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defTypedKVObjModel')
String → Model → Model → (* → Object | THROW)
Parameters
  • Stringname

    the name of the generated Model

  • ModelkeyModel

    The Model to validate keys against

  • ModelvalueModel

    The Model to validate values against

  • Returns:Object

    Returns an ObjectModel that can be called with an input

Returns an ObjectModel which will validate that an input is:

  • A Javascript Object
  • Has keys that validate against a Model
  • Has values that validate against a Model

It offers similar validation capabilities as ObjectModel's MapModel but the resulting Model accepts a Javascript object as input and returns a (proxied) Javascript object as output.

'use strict'
const defTypedKVObjModel = require('@eluvio/elv-js-helpers/ModelFactory/defTypedKVObjModel')

const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const NoBlankKVModel = defTypedKVObjModel(
  'NonBlankKV',
  NonBlankStrModel,
  NonBlankStrModel
)

NoBlankKVModel({})               //=> {}

NoBlankKVModel({foo: 'bar'})     //=> {foo: 'bar'}

NoBlankKVModel({foo: '   '})     //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: Value must not be a blank string (got: "   "))'

NoBlankKVModel({'  ': 'bar'})    //=> EXCEPTION: 'invalid property name "  " (is not a valid NonBlankString)'

NoBlankKVModel({foo: 42})        //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: expecting String, got Number 42)'

NoBlankKVModel(42)               //=> EXCEPTION: 'expecting Object, got Number 42'

dumpJSONMisc

const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')
* → undefined (PRINTS TO CONSOLE)

Pretty-prints value to console/stdout in JSON format. Like console.log(), returns undefined.

'use strict'
const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')

dumpJSON('A')           //=> OUTPUT: '"A"'

dumpJSON(42)            //=> OUTPUT: '42'

dumpJSON(undefined)     //=> OUTPUT: undefined

dumpJSON([1, 2, 3])     //=> OUTPUT: `[
                        //              1,
                        //              2,
                        //              3
                        //            ]`

dumpJSON({foo: 'bar'})  //=> OUTPUT: `{
                        //              "foo": "bar"
                        //            }`

dumpJSON(dumpJSON)      //=> OUTPUT: undefined

eitherFunctional

const either = require('@eluvio/elv-js-helpers/Functional/either')
(errVal → x) → (okVal → x) → Result errVal okVal → x
Parameters
  • function(unnamed)

    The function to apply to value contained in an Err

  • function(unnamed)

    The function to apply to value contained in an Ok

  • Returns:function

    Function which takes a Result and returns output of one of the two supplied functions

Passthrough for the either() Crocks point-free function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Result.html#either for more details on how to use with the Result ADT.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given two functions, returns a function that takes a Result and:

If the Result is an Err, calls the first function with the value wrapped by the Err If the Result is an Ok, calls the second function with the value wrapped by the Ok

'use strict'
const either = require('@eluvio/elv-js-helpers/Functional/either')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const resultToString = either(
  v => `Err result: (${v})`,
  v => `Ok result: (${v})`
)

resultToString(Ok(100))        //=> 'Ok result: (100)'
resultToString(Err('fail'))    //=> 'Err result: (fail)'

ErrADT

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
a → Err a
Parameters
  • Anyx

    The value to wrap in an Err

  • Returns:Result

Passthrough for the Err variety of the Result Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license), with automatic wrapping of non-array values to ensure proper concatenation of Err objects.

See https://crocks.dev/docs/crocks/Result.html for more details.

Allows users of elv-js-helpers to create Err objects without adding the Crocks package as a dependency, and following conventions of the elv-js-helpers package:

There are 2 kinds of Result objects, Ok and Err, that wrap successful and failed computations, respectively.

Result objects are useful for handling errors in functional pipelines and can collect multiple errors from various branches of a workflow.

Normally, one does not create generic Result object instances, but rather Ok or Err instances.

'use strict'
const Err = require('@eluvio/elv-js-helpers/ADT/Err')

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')
const liftA2 = require('@eluvio/elv-js-helpers/Functional/liftA2')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')
const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

const okObject = Ok(42)

// Non-array input automatically converted to 1-element array:
const errObject1 = Err('failed to obtain first input')
errObject1.inspect()                                          //=> 'Err [ "failed to obtain first input" ]'

const errObject2 = Err(['failed to obtain second input'])
errObject2.inspect()                                          //=> 'Err [ "failed to obtain second input" ]'

const mult = (a, b) => a * b

// convert function 'mult' into one that works with values wrapped in Ok / Err
const multResults = liftA2(curry(mult))

const goodResult = multResults(okObject, okObject)

goodResult.inspect()                                          //=> 'Ok 1764'

dumpJSON(resultToPOJO(goodResult))                            //=> OUTPUT: `{
                                                              //              "ok": true,
                                                              //              "value": 1764
                                                              //            }`

multResults(errObject1, okObject).inspect()                   //=> 'Err [ "failed to obtain first input" ]'

multResults(okObject, errObject2).inspect()                   //=> 'Err [ "failed to obtain second input" ]'

const resultTwoBadInputs = multResults(errObject1, errObject2)

resultTwoBadInputs.inspect()                                  //=> 'Err [ "failed to obtain first input", "failed to obtain second input" ]'

dumpJSON(resultToPOJO(resultTwoBadInputs))                    //=> OUTPUT: `{
                                                              //              "ok": false,
                                                              //              "errMsgs": [
                                                              //                "failed to obtain first input",
                                                              //                "failed to obtain second input"
                                                              //              ],
                                                              //              "errors": [
                                                              //                "failed to obtain first input",
                                                              //                "failed to obtain second input"
                                                              //              ]
                                                              //            }`

Err([])                                                       //=> EXCEPTION: 'Err cannot wrap an empty array'

Err([undefined]).inspect()                                    //=> 'Err [ undefined ]'

dumpJSON(resultToPOJO(Err([undefined])))                      //=> OUTPUT: `{
                                                              //              "ok": false,
                                                              //              "errMsgs": [
                                                              //                "undefined"
                                                              //              ],
                                                              //              "errors": [
                                                              //                null
                                                              //              ]
                                                              //            }`

escapeForRegExpConversion

const escapeForRegExp = require('@eluvio/elv-js-helpers/Conversion/escapeForRegExp')
* → String
Parameters
  • stringstr

    The value to escape

  • Returns:string

Escapes a string for use in a RegExp.

Useful if you need to match slashes and other special characters.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping

'use strict'
const escapeForRegExp = require('@eluvio/elv-js-helpers/Conversion/escapeForRegExp')

escapeForRegExp('foo')       //=> 'foo'

escapeForRegExp('/')         //=> '\/'

escapeForRegExp(42)          //=> EXCEPTION: 'str.replace is not a function'

estRemainingDurDatetime

const estRemainingDur = require('@eluvio/elv-js-helpers/Datetime/estRemainingDur')
Number → Number → Result [String] Number
Parameters
  • numbertimeElapsed

    The amount of Datetime taken so far

  • numberportionComplete

    A number between 0 and 1 (inclusive) representing progress

  • Returns:number

Estimates remaining duration based on portion completed expressed as a number between 0 and 1 and Datetime elapsed The function is unit-agnostic, but for most uses timeElapsed would be in seconds.

Returns a Crocks Ok instance wrapping a number if calculation succeeds. Returns a Crocks Err instance wrapping an array containing error(s) if passed bad inputs.

'use strict'
const estRemainingDur = require('@eluvio/elv-js-helpers/Datetime/estRemainingDur')

const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

estRemainingDur(21, 0.5).inspect()            //=> 'Ok 21'

estRemainingDur(42, 1).inspect()              //=> 'Ok 0'

const portionBadErr = estRemainingDur(42, 0)
resultToPOJO(portionBadErr).ok                //=> false
resultToPOJO(portionBadErr).errMsgs           //=> ['estRemainingDur: portionComplete must be > 0 and <= 1 (got: 0)']

const elapsedBadErr = estRemainingDur(0, .1)
resultToPOJO(elapsedBadErr).ok                //=> false
resultToPOJO(elapsedBadErr).errMsgs           //=> ['estRemainingDur: timeElapsed must be > 0 (got: 0)']

const bothBadErr = estRemainingDur(0, 0)
resultToPOJO(bothBadErr).ok                   //=> false
resultToPOJO(bothBadErr).errMsgs              //=> ['estRemainingDur: portionComplete must be > 0 and <= 1 (got: 0)', 'estRemainingDur: timeElapsed must be > 0 (got: 0)']

estTotalDurDatetime

const estTotalDur = require('@eluvio/elv-js-helpers/Datetime/estTotalDur')
Number → Number → Result [String] Number
Parameters
  • numbertimeElapsed

    The amount of Datetime taken so far

  • numberportionComplete

    A number between 0 and 1 (inclusive) representing progress

  • Returns:number

Estimates total duration based on portion completed expressed as a number between 0 and 1 and Datetime elapsed The function is unit-agnostic, but for most uses timeElapsed is in seconds.

Returns a Crocks Ok instance wrapping a number if calculation succeeds. Returns a Crocks Err instance wrapping an array containing error(s) if passed bad inputs.

'use strict'
const estTotalDur = require('@eluvio/elv-js-helpers/Datetime/estTotalDur')

const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

estTotalDur(21, 0.5).inspect()             //=> 'Ok 42'

estTotalDur(42, 1).inspect()               //=> 'Ok 42'

const portionBadErr = estTotalDur(42, 0)
resultToPOJO(portionBadErr).ok             //=> false
resultToPOJO(portionBadErr).errMsgs        // => ['estTotalDur: portionComplete must be > 0 and <= 1 (got: 0)']

const elapsedBadErr = estTotalDur(0, .1)
resultToPOJO(elapsedBadErr).ok             //=> false
resultToPOJO(elapsedBadErr).errMsgs        //=> ['estTotalDur: timeElapsed must be > 0 (got: 0)']

const bothBadErr = estTotalDur(0, 0)
resultToPOJO(bothBadErr).ok                //=> false
resultToPOJO(bothBadErr).errMsgs           //=>['estTotalDur: portionComplete must be > 0 and <= 1 (got: 0)', 'estTotalDur: timeElapsed must be > 0 (got: 0)']

etaDurStrDatetime

const etaDurStr = require('@eluvio/elv-js-helpers/Datetime/etaDurStr')
Number → String
Parameters
  • numbersecondsLeft

    The number of seconds remaining until completion

  • Returns:string

Returns an ETA expressed as number of days/hours/minutes/seconds remaining, based on a supplied value for how many seconds are left.

Unneeded larger units are omitted, and zero padding is suppressed for first number.

If secondsLeft is negative, returns '--'

'use strict'
const etaDurStr = require('@eluvio/elv-js-helpers/Datetime/etaDurStr')

etaDurStr(0)      //=> "0s"

etaDurStr(1)      //=> "1s"

etaDurStr(61)     //=> "1m 01s"

etaDurStr(3661)   //=> "1h 01m 01s"

etaDurStr(90061)  //=> "1d 01h 01m 01s"

etaDurStr(954061) //=> "11d 01h 01m 01s"

etaDurStr(-1)     //=> "--"

etaTimeStrDatetime

const etaTimeStr = require('@eluvio/elv-js-helpers/Datetime/etaTimeStr')
Date → Number → String
Parameters
  • DatecurrentTime

    Javascript Date object to use as current Datetime.

  • NumbersecondsLeft

    The number of seconds remaining until completion

  • Stringzone

    The Datetime zone in which to express ETA

  • Stringlocales

    The locale to use to format ETA

  • Returns:String

Returns an ETA Datetime or Datetime string based on a supplied value for current Datetime and how many seconds are left. The return string will include the month and day only if the ETA has a different date than currentTime (within the specified Datetime zone)

If secondsLeft is negative, returns '--'

Otherwise,

  • Bad values for currentTime / zone will return 'Invalid DateTime'
  • Unrecognized locale strings in locales will be ignored, and if none are recognized, it will be obtained from the system environment.
  • Passing in a value of incorrect type for locales will cause an exception.
'use strict'
const etaTimeStr = require('@eluvio/elv-js-helpers/Datetime/etaTimeStr')

const myTime = new Date('2022-01-01T07:30:00Z')

etaTimeStr(myTime, 10, 'America/Los_Angeles', 'en-US')   //=> "11:30:10 PM PST"

etaTimeStr(myTime, 3600, 'America/Los_Angeles', 'en-US') //=> "Jan 1, 12:30:00 AM PST"

etaTimeStr(myTime, -10, 'America/Los_Angeles', 'en-US')  //=> "--"

etaTimeStr(myTime, 10, 'foo', 'en-US')                   //=> EXCEPTION: "Invalid time zone specified: foo"

FFunctional

const F = require('@eluvio/elv-js-helpers/Functional/F')
{} → a
Parameters
  • Returns:Boolean

    false

Ignores input and always returns false.

Used for composing functional workflows, often indicating 'never'.

'use strict'
const F = require('@eluvio/elv-js-helpers/Functional/F')

F(42)   //=> false

F()     //=> false

failsModelCheckBoolean

const failsModelCheck = require('@eluvio/elv-js-helpers/Boolean/failsModelCheck')
Model → * → Boolean
λcurried function
Parameters
  • ModelModel

    The Model to test against

  • Anyinput

    The value to test

  • Returns:Boolean

Returns true if the specified Model fails to validate an input, false otherwise.

Used when the caller does not care about the details of why the input failed validation.

'use strict'
const failsModelCheck = require('@eluvio/elv-js-helpers/Boolean/failsModelCheck')

const PositiveIntModel = require('@eluvio/elv-js-helpers/Model/PositiveIntModel')

failsModelCheck(PositiveIntModel, 1)  //=> false

failsModelCheck(PositiveIntModel, -1) //=> true

// function is curried: call with just first param to obtain a narrower function
const isNotPositiveInt = failsModelCheck(PositiveIntModel)

isNotPositiveInt(1)                   //=> false

isNotPositiveInt(0)                   //=> true

isNotPositiveInt('foo')               //=> true

filterFunctional

const filter = require('@eluvio/elv-js-helpers/Functional/filter')
((*) → *) → [*] → [*]
λcurried function
Parameters
  • function(unnamed)

    the test function, accepting a list element and returning a truthy value if the element should be included in result list

  • List(unnamed)

    an iterable list of elements

  • Returns:Array

    The elements where function evaluated

Passthrough for Ramda's filter function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Tests elements of a list with a function and returns a new list containing the elements where the function evaluates to a truthy value.

'use strict'
const filter = require('@eluvio/elv-js-helpers/Functional/filter')

const arrOfInt = [1, 2, 3, 4, 5]

const isEven = a => a % 2 === 0

filter(isEven, arrOfInt)      //=> [2, 4]

// Function is curried, call with fewer arguments to get a new, more specific function

const isOdd = a => a % 2 === 1

const filterOdd = filter(isOdd)

filterOdd(arrOfInt)           //=> [1, 3, 5]

findFunctional

const find = require('@eluvio/elv-js-helpers/Functional/find')
((*) → *) → [*] → *
λcurried function
Parameters
  • function(unnamed)

    the test function, accepting a list element and returning a truthy value if the element satisfies condition

  • List(unnamed)

    an iterable list of elements

  • Returns:Any

    The first element that satisfies condition, or undefined if no element does

Passthrough for Ramda's find function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns first element of a list where test function evaluates to a truthy value.

'use strict'
const find = require('@eluvio/elv-js-helpers/Functional/find')
const isGTE = require('@eluvio/elv-js-helpers/Boolean/isGTE')

const arrOfInt = [1, 2, 3, 4, 5]

const isEven = a => a % 2 === 0
const gte10 = isGTE(10)

find(isEven, arrOfInt)      //=> 2

find(gte10, arrOfInt)       //=> undefined

// Function is curried, call with fewer arguments to get a new, more specific function

const isOdd = a => a % 2 === 1

const firstOdd = find(isOdd)

firstOdd(arrOfInt)          //=> 1

flattenFunctional

const flatten = require('@eluvio/elv-js-helpers/Functional/flatten')
List → List
Parameters
  • Arrayx

    the list to flatten

  • Returns:Array

    The flattened list

Passthrough for Ramda's flatten function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a new list by pulling every item out of it (and all its sub-arrays) and putting them in a new array, depth-first.

'use strict'
const flatten = require('@eluvio/elv-js-helpers/Functional/flatten')

flatten([1, [2, [3]]])         //=> [1, 2, 3]

flatten("abc")                 //=> ['a', 'b', 'c']

flipFunctional

const flip = require('@eluvio/elv-js-helpers/Functional/flip')
(a → b → c) → b → a → c
λcurried function
Parameters
  • function(unnamed)

    A 2-input function

  • Returns:function
    • A curried 2-input function that reverses the order of inputs before passing to the original function

Passthrough for the flip() Crocks combinator (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/combinators.html#flip for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given a 2-input function, returns a new function with the order of inputs reversed.

'use strict'
const flip = require('@eluvio/elv-js-helpers/Functional/flip')

const div = (a, b) => a/b

div(4, 2)            //=> 2

const reciprocalDiv = flip(div)

reciprocalDiv(4, 2)  //=> 0.5

// flip is curried, it is possible to call with all arguments at once

flip(div, 4, 2)      //=> 0.5

formatConversion

const format = require('@eluvio/elv-js-helpers/Conversion/format')
* → String
Parameters
  • Anyvalue

    The value to format

  • Returns:String

Passthrough for the format() function from @ladjs/format-util _(Copyright © 2015 Freeform Systems and other contributors, MIT license).

Allows users of elv-js-helpers to use the function without adding the @ladjs/format-util package as a dependency.

Converts input to a string for use in error messages and log statements.

Similar to format() from the node:util module but without the code size overhead of using that module.

'use strict'
const format = require('@eluvio/elv-js-helpers/Conversion/format')

format(' ')      //=> '" "'

format(42)       //=> '42'

format(x => x*2) //=> '[Function (anonymous)]'

format(format)   //=> '[Function: format]'

fracStrToNumConversion

const fracStrToNum = require('@eluvio/elv-js-helpers/Conversion/fracStrToNum')
string → number
Parameters
  • Stringstr

    A string representing a fraction or whole number

  • Returns:Number

Evaluates string as a rational number using fraction.js and converts to a number.

'use strict'
const fracStrToNum = require('@eluvio/elv-js-helpers/Conversion/fracStrToNum')

fracStrToNum('1')        //=> 1

fracStrToNum('1/2')      //=> 0.5

fracStrToNum(9)          //=> EXCEPTION: 'expecting String, got Number 9'

fracStrToNum('1/0')      //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "1/0")'

fracStrToNum('0/1')      //=> 0

fractionConversion

const fraction = require('@eluvio/elv-js-helpers/Conversion/fraction')
String | Number → Object
Parameters
  • String(unnamed)

    The value to convert into a fraction.js object

  • Returns:Object

    A fraction.js object

Passthrough for the fraction.js constructor (Copyright © 2017 Robert Eisele, MIT license)

See https://www.npmjs.com/package/fraction.js for more details.

Provided for convenience and to encourage standardization.

Accepts a number or string representation of a rational number and returns a fraction.js object.

'use strict'
const fraction = require('@eluvio/elv-js-helpers/Conversion/fraction')

fraction(4.2).toFraction(true)   //=> '4 1/5'

fraction('foo').toFraction(true) //=> EXCEPTION: 'Invalid argument'

fraction('1/0').toFraction(true) //=> EXCEPTION: 'Division by Zero'

fraction(4.2).toFraction(true)   //=> '4 1/5'

fraction('22/7').valueOf()       //=> 3.142857142857143

// .s returns sign:
fraction('-22/7').s              //=> -1

// .n returns numerator
fraction('-22/7').n              //=> 22

// .d returns denominator
fraction('-22/7').d              //=> 7

fraction('9 3/4').valueOf()      //=> 9.75

FractionStrModelModel

const FractionStrModel = require('@eluvio/elv-js-helpers/Model/FractionStrModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is:

  • A Javascript String
  • Is in the form 'x/y', '-x/y', 'x', or '-x' where x and y are integers and y != 0

Leading zeroes are allowed, e.g. '001/002'

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const FractionStrModel = require('@eluvio/elv-js-helpers/Model/FractionStrModel')

FractionStrModel('foo')  //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "foo")'

FractionStrModel('  ')   //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "  ")'

FractionStrModel(42)     //=> EXCEPTION: 'expecting String, got Number 42'

FractionStrModel('42')   //=> '42'

FractionStrModel('0')    //=> '0'

FractionStrModel('-42')  //=> '-42'

FractionStrModel('42/2') //=> '42/2'

FractionStrModel('42/0') //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "42/0")'

fracToNumConversion

const fracToNum = require('@eluvio/elv-js-helpers/Conversion/fracToNum')
Object → Number | EXCEPTION
Parameters
  • Objectf

    A fraction.js object

  • Returns:Number

    The Javascript number representation of the fraction

Convert a fraction.js object to a Javascript number. (fraction.js Copyright © 2017 Robert Eisele, MIT license)

See https://www.npmjs.com/package/fraction.js for more details.

Provided for use in function composition.

Accepts a fraction.js object and returns a Javascript number.

'use strict'
const fracToNum = require('@eluvio/elv-js-helpers/Conversion/fracToNum')

const fraction = require('@eluvio/elv-js-helpers/Conversion/fraction')

const myFraction = fraction(4.2)

fracToNum(myFraction)         //=> 4.2

const pi = fraction('22/7')

fracToNum(pi)                 //=> 3.142857142857143

fracToNum('22/7')              //=> EXCEPTION: 'Value is not a fraction.js object'

fromPairsConversion

const fromPairs = require('@eluvio/elv-js-helpers/Conversion/fromPairs')
List (Pair String a) → Object
Parameters
  • List(unnamed)

    The List of key, value Pairs

  • Returns:Object

Passthrough for the fromPairs() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/helpers.html#frompairs for more details.

Creates an object from a Crocks List of Pair objects, with each Pair containing key as first element and value as second element.

Not to be confused with Ramda's fromPairs() function, which takes a 2-level regular Javascript array as input.

See also objFromEntries, toPairs

'use strict'
const fromPairs = require('@eluvio/elv-js-helpers/Conversion/fromPairs')

const List = require('@eluvio/elv-js-helpers/ADT/List')
const Pair = require('@eluvio/elv-js-helpers/ADT/Pair')

const kvPairs = List([Pair('a', 1), Pair('b',2)])

fromPairs(kvPairs)     //=> { a: 1, b: 2 }

FunctionModelModel

const FunctionModel = require('@eluvio/elv-js-helpers/Model/FunctionModel')
* → *
Parameters
  • Any(unnamed)

    Any input

  • Returns:*

    The input

Validates that an input is a function

getPathFunctional

const getPath = require('@eluvio/elv-js-helpers/Functional/getPath')
Idx = String | Int | Symbol => [Idx] → {a} → a | Undefined
λcurried function
Parameters
  • ArraypathArray

    the path to retrieve, expressed as an array

  • Objectobject

    the object to retrieve path from

  • Returns:*

    Value or undefined

Renamed passthrough for Ramda's path function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Gets value at specified path from object, or undefined if not found.

Supports negative numbers as indexes, to retrieve element counting from end of array

'use strict'
const getPath = require('@eluvio/elv-js-helpers/Functional/getPath')

const myObject = {foo: {bar: [1, 2, 3]}}

getPath(['foo'], myObject)                //=> {bar: [1, 2, 3]}

getPath(['bar'], myObject)                //=> undefined

getPath(['foo', 'bar', 0], myObject)      //=> 1

getPath(['foo', 'bar', -1], myObject)     //=> 3

getPropFunctional

const getProp = require('@eluvio/elv-js-helpers/Functional/getProp')
Idx = String | Int | Symbol => Idx → Object | Array → a | Undefined
λcurried function
Parameters
  • Stringprop

    the property (or index) to retrieve

  • Objectitem

    the item to retrieve property or element from

  • Returns:*

    Value or undefined

Renamed passthrough for Ramda's prop function (Copyright © Scott Sauyet and Michael Hurley) Not to be confused with Crocks getProp(), which returns a Maybe

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Gets value of specified property or index from object, or undefined if not found.

Supports negative numbers as indexes, to retrieve element counting from end of array

'use strict'
const getProp = require('@eluvio/elv-js-helpers/Functional/getProp')

const myObject = {foo: {bar: [1, 2, 3]}}

getProp('foo', myObject)                //=> {bar: [1, 2, 3]}

getProp('bar', myObject)                //=> undefined

const myArray = [0, 1, 2]

getProp(0, myArray)      //=> 0

getProp(-1, myArray)     //=> 2

groupByFunctional

const groupBy = require('@eluvio/elv-js-helpers/Functional/groupBy')
((*) → String | Int | Symbol) → [*] → [*]
λcurried function
Parameters
  • function(unnamed)

    the classifier function, accepting a list element and returning a valid object key (string, int or symbol)

  • List(unnamed)

    an iterable list of elements

  • Returns:Object

    The object containing sublists grouped by return value of the classifier function

Passthrough for Ramda's groupBy function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Groups elements of a list by the return value of a classifier function and returns an object where the keys are the classifier function return values and the values are list of elements that evaluated to those return values.

'use strict'
const groupBy = require('@eluvio/elv-js-helpers/Functional/groupBy')

const values = [1, 2, [3], 'a', 'b', null]

const kind = require('@eluvio/elv-js-helpers/Validation/kind')

groupBy(kind, values)      //=> {Array: [[3]], Number: [1, 2], null: [null], String: ['a','b']}

growthMath

const growth = require('@eluvio/elv-js-helpers/Math/growth')
Number → Number → Number
λcurried function
Parameters
  • NumberoldValue

    starting (baseline) value

  • NumbernewValue

    ending value for calculating growth amount

  • Returns:Number

    growth expressed as a proportion of the absolute value of the first value

Calculates change between 2 values, expressed as a proportion of the (absolute value of) first value, e.g.:

  • Returns 0 if both values are the same
  • Returns 0.5 if second value is 50% bigger than the first value
  • Returns -0.5 if second value is 50% smaller than the first value

Note that if the first value is 0 the return value will be:

  • Infinity if the second value is positive
  • -Infinity if the second value is negative
  • 0 if the second value is zero

Note that if the first value is negative, "growth" is defined as "becoming less negative", e.g. growth(-100, 0) == 1

'use strict'
const growth = require('@eluvio/elv-js-helpers/Math/growth')

// Positive starting value
growth(42, 420)        //=> 9

growth(42, 84)         //=> 1

growth(42, 63)         //=> 0.5

growth(42, 42)         //=> 0

growth(42, 21)         //=> -0.5

growth(42, 0)          //=> -1

growth(42, -42)        //=> -2

// Negative starting value
growth(-42, -84)       //=> -1

growth(-42, 0)         //=> 1

growth(-42, 42)        //=> 2

// Zero starting value
growth(0, 1)           //=> Infinity
growth(0, 0)           //=> 0
growth(0, -1)          //=> -Infinity

hasNoDuplicatesBoolean

const hasNoDuplicates = require('@eluvio/elv-js-helpers/Boolean/hasNoDuplicates')
Array → Boolean
Parameters
  • Arrayarr

    The value to test

  • Returns:Boolean

Returns true if passed an array with no duplicate elements. Returns false if passed an array that has duplicate element(s). Throws error if passed anything but an array.

Uses _Set from Ramda (Copyright © Scott Sauyet and Michael Hurley) to determine whether two elements are equivalent, so should handle cyclical data structures, comparison of equivalent objects, functions, and so forth.

'use strict'
const hasNoDuplicates = require('@eluvio/elv-js-helpers/Boolean/hasNoDuplicates')

hasNoDuplicates([])                       //=> true

hasNoDuplicates([1, 2, 3])                //=> true

hasNoDuplicates([1, 2, 2])                //=> false

hasNoDuplicates([[1, 2], [1, 2]])         //=> false

hasNoDuplicates([[1, 2], [2, 1]])         //=> true

hasNoDuplicates([[1, 1], [2, 2]])         //=> true

hasNoDuplicates([{a:1, b:2}, {b:2, a:1}]) //=> false

hasNoDuplicates('foo')                    //=> EXCEPTION: 'hasNoDuplicates() - expecting Array, got: String'

headFunctional

const head = require('@eluvio/elv-js-helpers/Functional/head')
[*] → * | undefined | EXCEPTION
String → String
Parameters
  • List(unnamed)

    an iterable list of elements

  • Returns:Any

    First element of array or first character of string

Passthrough for Ramda's head function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns first element of a list or last character of a string, or undefined if there is no first element, and empty string if there is no last character

See also init, last, tail

'use strict'
const head = require('@eluvio/elv-js-helpers/Functional/head')

head([1, 2, 3, 4, 5])      //=> 1
head([1])                  //=> 1
head([])                   //=> undefined

head('abc')                //=> 'a'
head('a')                  //=> 'a'
head('')                   //=> ''

// NOTE: bad data types are ignored
head(0)                    //=> undefined

head({foo: 'bar'})         //=> undefined

// undefined will produce an exception
head(undefined)            //=> EXCEPTION: 'Cannot read properties of undefined'

identityFunctional

const identity = require('@eluvio/elv-js-helpers/Functional/identity')
a → a
Parameters
  • Anyx

    The input value

  • Returns:*

    The input value

Given an input, returns that input. Used for composing functional workflows, often indicating 'no-op'.

'use strict'
const identity = require('@eluvio/elv-js-helpers/Functional/identity')

identity(42)   //=> 42

ifElseFunctional

const ifElse = require('@eluvio/elv-js-helpers/Functional/ifElse')
(a → boolean) → (a → b) → (a → b) → a → b
Parameters
  • function(unnamed)

    The boolean test function

  • function(unnamed)

    The function to apply to value if test function returns true

  • function(unnamed)

    The function to apply to value if test function returns false

  • Returns:function

    Function which takes a value and returns output of one of the latter two functions

Passthrough for the ifElse() Crocks point-free function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/logic-functions.html#ifelse for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given 3 functions (a boolean function and two additional functions), returns a function that takes a value and, if function1(value) is true, returns function2(value), else returns function3(value)

'use strict'
const ifElse = require('@eluvio/elv-js-helpers/Functional/ifElse')

const isEven = x => x % 2 === 0
const half = x => x/2
const triplePlusOne = x => 3 *x + 1

const collatz = ifElse(
  isEven,
  half,
  triplePlusOne
)

collatz(3)       //=> 10
collatz(10)      //=> 5

initFunctional

const init = require('@eluvio/elv-js-helpers/Functional/init')
[*] → [*] | EXCEPTION
String → String
Parameters
  • List(unnamed)

    an iterable list of elements

  • Returns:Array

    Array containing all but the last element, or String containing all but the last character

Passthrough for Ramda's init function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns all but the last element of a list or string

See also head, last, tail

'use strict'
const init = require('@eluvio/elv-js-helpers/Functional/init')

init([1, 2, 3, 4, 5])      //=> [1, 2, 3, 4]
init([1])                  //=> []
init([])                   //=> []

init('abc')                //=> 'ab'
init('a')                  //=> ''
init('')                   //=> ''

// NOTE: bad data types are ignored
init(0)                    //=> []

init({foo: 'bar'})         //=> []

// undefined will produce an exception
init(undefined)            //=> EXCEPTION: 'Cannot read properties of undefined'

IntegerModelModel

const IntegerModel = require('@eluvio/elv-js-helpers/Model/IntegerModel')
* → Integer | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Integer

    The validated input

An ObjectModel which validates that an input is:

If input passes validation, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const IntegerModel = require('@eluvio/elv-js-helpers/Model/IntegerModel')

IntegerModel(42)    //=> 42

IntegerModel(4.2)   //=> EXCEPTION: 'Value must be an integer (got: 4.2)'

IntegerModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

IntegerModel(Infinity) //=> EXCEPTION: 'Value must be an integer (got: Infinity)'

IntegerModel(-Infinity) //=> EXCEPTION: 'Value must be an integer (got: -Infinity)'

isArrayBoolean

const isArray = require('@eluvio/elv-js-helpers/Boolean/isArray')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed an array. Returns false if passed anything else

'use strict'
const isArray = require('@eluvio/elv-js-helpers/Boolean/isArray')

isArray([1, 2, 3]) //=> true

isArray(1, 2, 3)   //=> false

isArray('foo')     //=> false

isBase58StringBoolean

const isBase58String = require('@eluvio/elv-js-helpers/Boolean/isBase58String')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a valid Base58 string. Returns false if passed anything else.

'use strict'
const isBase58String = require('@eluvio/elv-js-helpers/Boolean/isBase58String')

isBase58String('foo')            //=> true

isBase58String('FOO')            //=> false

isBase58String(1, 2, 3)          //=> false

// extra arguments are ignored
isBase58String('foo', 2, 3)      //=> true

isEmptyBoolean

const isEmpty = require('@eluvio/elv-js-helpers/Boolean/isEmpty')
a → → Boolean
λcurried function
Parameters
  • Any(unnamed)

    The value to test

  • Returns:Boolean

Passthrough for the Ramda isEmpty function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns true if a value is the empty value for its type, false otherwise.

'use strict'
const isEmpty = require('@eluvio/elv-js-helpers/Boolean/isEmpty')

isEmpty([42])                //=> false

isEmpty([])                  //=> true

isEmpty('')                  //=> true

isEmpty(null)                //=> false

isEmpty({})                  //=> true

isEmpty({foo: 'bar'})        //=> false

isEqualBoolean

const isEqual = require('@eluvio/elv-js-helpers/Boolean/isEqual')
a → Boolean
λcurried function
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Compares 2 values using Javascript's Strict equality operator (===)

Returns true if value1 === value2 Returns false otherwise

To compare two arrays or objects for equivalence, use isEquivalent instead.

'use strict'
const isEqual = require('@eluvio/elv-js-helpers/Boolean/isEqual')

isEqual(42, 42)       //=> true

isEqual(42, '42')     //=> false

isEqual([1], [1])     //=> false

// function is curried: can call with fewer params to obtain a more specific function:
const equals42 = isEqual(42)

equals42(0)           //=> false

equals42(42)          //=> true

isEquivalentBoolean

const isEquivalent = require('@eluvio/elv-js-helpers/Boolean/isEquivalent')
a → b → Boolean
λcurried function
Parameters
  • Any(unnamed)

    The first value to compare

  • Any(unnamed)

    The second value to compare

  • Returns:Boolean

Renamed passthrough for the Ramda equals function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Compares two values for equivalence, meaning it can compare arrays, objects, and functions. Also handles cyclical data structures.

const isEquivalent = require('@eluvio/elv-js-helpers/Boolean/isEquivalent')

isEquivalent(42, 42)             //=> true

isEquivalent(42, '42')           //=> false

isEquivalent([42], [42])         //=> true

// element order matters for arrays
isEquivalent([1, 42], [1, 42])   //=> true
isEquivalent([1, 42], [42, 1])   //=> false

// property order in objects does not matter
const obj1 = {foo: 42, bar: 1}
const obj2 = {bar: 1, foo: 42}
isEquivalent(obj1, obj2)         //=> true

// function is curried: can call with fewer params to obtain a more specific function:
const isEmptyObject = isEquivalent({})

isEmptyObject({})           //=> true

isEmptyObject(42)           //=> false

isErrBoolean

const isErr = require('@eluvio/elv-js-helpers/Boolean/isErr')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a Crocks Err instance. Returns false if passed anything else

'use strict'
const isErr = require('@eluvio/elv-js-helpers/Boolean/isErr')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

isErr(Err(['invalid query'])) //=> true

isErr(Ok(42))                 //=> false

isErr('foo')                  //=> false

isFractionBoolean

const isFraction = require('@eluvio/elv-js-helpers/Boolean/isFraction')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a fraction.js object. fraction.js (Copyright © 2017 Robert Eisele, MIT license)

Returns false if passed anything else

'use strict'
const isFraction = require('@eluvio/elv-js-helpers/Boolean/isFraction')

const fraction = require('@eluvio/elv-js-helpers/Conversion/fraction')

const twoOverOne = fraction('2')
const sortOfPi = fraction('22/7')

isFraction(twoOverOne)  //=> true
isFraction(sortOfPi)    //=> true

isFraction(22/7)        //=> false

isFraction(Infinity)    //=> false

isFraction(NaN)         //=> false

isFraction('foo')       //=> false

isFunctionBoolean

const isFunction = require('@eluvio/elv-js-helpers/Boolean/isFunction')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a function. Returns false if passed anything else

'use strict'
const isFunction = require('@eluvio/elv-js-helpers/Boolean/isFunction')

isFunction([1, 2, 3])   //=> false

isFunction(1, 2, 3)     //=> false

isFunction('foo')       //=> false

isFunction(isFunction)  //=> true

isGeneratorFunctionBoolean

const isGeneratorFunction = require('@eluvio/elv-js-helpers/Boolean/isGeneratorFunction')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a GeneratorFunction.

Returns false if passed anything else

'use strict'
const isGeneratorFunction = require('@eluvio/elv-js-helpers/Boolean/isGeneratorFunction')

function* numbersUpTo(x) {
  for (let i = 0; i < x; i++) {
    yield i
  }
}

isGeneratorFunction(numbersUpTo)      //=> true

isGeneratorFunction(Math.round)       //=> false

isGeneratorFunction(undefined)        //=> false

isGTBoolean

const isGT = require('@eluvio/elv-js-helpers/Boolean/isGT')
* → * → Boolean
λcurried function
Parameters
  • Any(unnamed)

    the first value to compare

  • Any(unnamed)

    the second value to compare

  • Returns:Boolean

Returns true if SECOND input is greater than the FIRST input, false otherwise.

Note that this is the REVERSE of normal infix notation, as well as Ramda's gt function - this is to allow more intuitive currying, e.g. isGreaterThan42 = isGT(42)

If called with fewer than 2 arguments, will return a partially applied function

Uses the Javascript Greater than operator (>) to perform the comparison.

'use strict'
const isGT = require('@eluvio/elv-js-helpers/Boolean/isGT')

isGT(1, 42)             //=> true

isGT(42, 1)             //=> false

isGT(42, 42)            //=> false

isGT(null, undefined)   //=> false

isGT(undefined, null)   //=> false

// function is curried: can call with fewer params to obtain a narrower function
const isPositive = isGT(0)

isPositive(-1)          //=> false

isPositive(0)           //=> false

isPositive(1)           //=> true

isGTCustomBoolean

const isGTCustom = require('@eluvio/elv-js-helpers/Boolean/isGTCustom')
(* → *) → * → * → Boolean
λcurried function
Parameters
  • functionpreprocessFn

    function to use to preprocess inputs, to allow them to be compared with >

  • Anyvalue1

    the first value to compare

  • Anyvalue2

    the second value to compare

  • Returns:Boolean

Preprocesses 2 inputs individually using a specified function, then compares them and returns true if SECOND input is greater than the FIRST input, false otherwise.

Note that order of arguments for comparison is the reverse of Ramda's gt function, this is to allow more intuitive currying.

The preprocessor function needs to make the inputs directly comparable using the standard > operator. (i.e. this function does the equivalent of return preProcessorFn(value1) > preProcessorFn(value2)

If called with fewer than 3 arguments, will return a partially applied function

'use strict'
const isGTCustom = require('@eluvio/elv-js-helpers/Boolean/isGTCustom')

const strLength = str => str.length
const isLongerThan = isGTCustom(strLength)

isLongerThan('a', 'ab')                               //=> true

isLongerThan('ab', 'a')                               //=> false

// x.length returns undefined for x === 42, undefined > undefined returns false:
isLongerThan(42, 42)                                  //=> false

isLongerThan(null, undefined)                         //=> EXCEPTION: "Cannot read properties of null (reading 'length')"

// function is curried: can call with more than 1 argument

// example: call with 2 args
const isLongerThan3Chars = isGTCustom(strLength, 'foo')

isLongerThan3Chars('bar')                             //=> false

isLongerThan3Chars('foobar')                          //=> true

// example: call with 3 args
isGTCustom(strLength, 'foo', 'bar')                   //=> false

isGTCustom(strLength, 'foo', 'foobar')                //=> true

isGTEBoolean

const isGTE = require('@eluvio/elv-js-helpers/Boolean/isGTE')
* → * → Boolean
λcurried function
Parameters
  • Any(unnamed)

    the first value to compare

  • Any(unnamed)

    the second value to compare

  • Returns:Boolean

Returns true if SECOND input is greater than or equal to the FIRST input, false otherwise.

Note that this is the REVERSE of normal infix notation, as well as Ramda's gte function - this is to allow more intuitive currying, e.g. isAtLeast42 = isGTE(42)

If called with fewer than 2 arguments, will return a partially applied function

Uses the Javascript Greater than or equal operator (>=) to perform the comparison.

'use strict'
const isGTE = require('@eluvio/elv-js-helpers/Boolean/isGTE')

isGTE(1, 42)             //=> true

isGTE(42, 1)             //=> false

isGTE(42, 42)            //=> true

isGTE(null, undefined)   //=> false

// function is curried: can call with fewer params to obtain a narrower function
const notNegative = isGTE(0)

notNegative(-1)          //=> false

notNegative(0)           //=> true

notNegative(1)           //=> true

isLTBoolean

const isLT = require('@eluvio/elv-js-helpers/Boolean/isLT')
* → * → Boolean
λcurried function
Parameters
  • Any(unnamed)

    the first value to compare

  • Any(unnamed)

    the second value to compare

  • Returns:Boolean

Returns true if SECOND input is less than the FIRST input, false otherwise.

Note that this is the REVERSE of normal infix notation, as well as Ramda's lt function - this is to allow more intuitive currying, e.g. isLessThan42 = isLT(42)

If called with fewer than 2 arguments, will return a partially applied function

Uses the Javascript Less than operator (<) to perform the comparison.

'use strict'
const isLT = require('@eluvio/elv-js-helpers/Boolean/isLT')

isLT(42, 1)             //=> true

isLT(1, 42)             //=> false

isLT(42, 42)            //=> false

isLT(null, undefined)   //=> false

isLT(undefined, null)   //=> false

// function is curried: can call with fewer params to obtain a narrower function
const isNegative = isLT(0)

isNegative(-1)          //=> true

isNegative(0)           //=> false

isNegative(1)           //=> false

isLTEBoolean

const isLTE = require('@eluvio/elv-js-helpers/Boolean/isLTE')
* → * → Boolean
λcurried function
Parameters
  • Any(unnamed)

    the first value to compare

  • Any(unnamed)

    the second value to compare

  • Returns:Boolean

Returns true if SECOND input is less than or equal to the FIRST input, false otherwise.

Note that this is the REVERSE of normal infix notation, as well as Ramda's lte function - this is to allow more intuitive currying, e.g. isAtMost42 = isLTE(42)

If called with fewer than 2 arguments, will return a partially applied function

Uses the Javascript Less than or equal operator (<=) to perform the comparison.

'use strict'
const isLTE = require('@eluvio/elv-js-helpers/Boolean/isLTE')

isLTE(42, 1)             //=> true

isLTE(1, 42)             //=> false

isLTE(42, 42)            //=> true

isLTE(null, undefined)   //=> false

isLTE(undefined, null)   //=> false

// function is curried: can call with fewer params to obtain a narrower function
const notPositive = isLTE(0)

notPositive(-1)          //=> true

notPositive(0)           //=> true

notPositive(1)           //=> false

isModelBoolean

const isModel = require('@eluvio/elv-js-helpers/Boolean/isModel')
* → Boolean
Parameters
  • Anyx

    the item to check

  • Returns:Boolean

Returns true if passed in a validation Model, false otherwise.

Note that a ModelFactory is not a Model, but the output of a ModelFactory is.

'use strict'
const isModel = require('@eluvio/elv-js-helpers/Boolean/isModel')

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

isModel(42)                           //=> false

isModel(NonBlankStrModel)             //=> true

isModel(defObjectModel)               //=> false

const PersonModel = defObjectModel('PersonName', {first: String, last: String})

isModel(PersonModel)                  //=> true

const validatedPerson = PersonModel({
  first: 'Arthur',
  last: 'Dent'
})

isModel(validatedPerson)              //=> false

isNilBoolean

const isNil = require('@eluvio/elv-js-helpers/Boolean/isNil')
* → Boolean
Parameters
  • Anyvalue

    the value to test

  • Returns:Boolean

Returns true if value is null or undefined, otherwise returns false

Copies functionality of the Ramda function of the same name (Copyright © Scott Sauyet and Michael Hurley)

'use strict'
const isNil = require('@eluvio/elv-js-helpers/Boolean/isNil')

isNil()                //=> true

isNil(undefined)       //=> true

isNil(null)            //=> true

isNil(42)              //=> false

// extra argument ignored:
isNil(42, undefined)   //=> false

// extra argument ignored:
isNil(undefined, 42)   //=> true

isNotEmptyBoolean

const isNotEmpty = require('@eluvio/elv-js-helpers/Boolean/isNotEmpty')
a → → Boolean
λcurried function
Parameters
  • Any(unnamed)

    The value to test

  • Returns:Boolean

Negated version of the Ramda isEmpty function (Copyright © Scott Sauyet and Michael Hurley)

Returns false if a value is the empty value for its type, true otherwise.

'use strict'
const isNotEmpty = require('@eluvio/elv-js-helpers/Boolean/isNotEmpty')

isNotEmpty([42])                //=> true

isNotEmpty([])                  //=> false

isNotEmpty('')                  //=> false

isNotEmpty(null)                //=> true

isNotEmpty({})                  //=> false

isNotEmpty({foo: 'bar'})        //=> true

isNullBoolean

const isNull = require('@eluvio/elv-js-helpers/Boolean/isNull')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed null. Returns false if passed anything else

'use strict'
const isNull = require('@eluvio/elv-js-helpers/Boolean/isNull')

isNull(null)              //=> true

isNull()                  //=> false

isNull(undefined)         //=> false

isNull(0)                 //=> false

// extra arguments ignored:
isNull(1, null, null)     //=> false

isNull('foo')             //=> false

// extra argument ignored:
isNull(null, 3)           //=> true

isNumberBoolean

const isNumber = require('@eluvio/elv-js-helpers/Boolean/isNumber')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a Number. Returns false if passed anything else

'use strict'
const isNumber = require('@eluvio/elv-js-helpers/Boolean/isNumber')

isNumber(1)          //=> true

isNumber(Infinity)   //=> true

isNumber(NaN)        //=> true

isNumber('foo')      //=> false

isObjectBoolean

const isObject = require('@eluvio/elv-js-helpers/Boolean/isObject')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed an object. Returns false if passed anything else

'use strict'
const isObject = require('@eluvio/elv-js-helpers/Boolean/isObject')

isObject([1, 2, 3])         //=> false

// extra argument ignored:
isObject(1, {foo: 'bar'})   //=> false

isObject('foo')             //=> false

isObject({})                //=> true

// extra argument ignored:
isObject({foo: 'bar'}, 3)   //=> true

isOfKindBoolean

const isOfKind = require('@eluvio/elv-js-helpers/Boolean/isOfKind')
String → * → Boolean
λcurried function
Parameters
  • StringkindName

    Lower case string expected when value is passed to kind-of.

  • Anyx

    The value to test

  • Returns:Boolean

Returns true if value is of the specified type, false otherwise.

The type is determined using the kind function.

'use strict'
const isOfKind = require('@eluvio/elv-js-helpers/Boolean/isOfKind')

isOfKind('Array', [1, 2, 3]) //=> true

isOfKind('Array', 1, 2, 3)   //=> false

isOfKind('Array', 'foo')     //=> false

isOkBoolean

const isOk = require('@eluvio/elv-js-helpers/Boolean/isOk')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a Crocks Ok instance. Returns false if passed anything else

'use strict'
const isOk = require('@eluvio/elv-js-helpers/Boolean/isOk')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

isOk(Err(['invalid query'])) //=> false

isOk(Ok(42))                 //=> true

isOk('foo')                  //=> false

isRegExpBoolean

const isRegExp = require('@eluvio/elv-js-helpers/Boolean/isRegExp')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a regular expression. Returns false if passed anything else

'use strict'
const isRegExp = require('@eluvio/elv-js-helpers/Boolean/isRegExp')

isRegExp([1, 2, 3])         //=> false

// extra arguments ignored:
isRegExp(1, /foo/)   //=> false

isRegExp(/foo/)             //=> true

// extra argument ignored:
isRegExp(/foo/, 3)          //=> true

isResultBoolean

const isResult = require('@eluvio/elv-js-helpers/Boolean/isResult')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a Crocks Result instance. Returns false if passed anything else

'use strict'
const isResult = require('@eluvio/elv-js-helpers/Boolean/isResult')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

isResult(Err(['invalid query'])) //=> true

isResult(Ok(42))                 //=> true

isResult('foo')                  //=> false

isStringBoolean

const isString = require('@eluvio/elv-js-helpers/Boolean/isString')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed a string. Returns false if passed anything else

'use strict'
const isString = require('@eluvio/elv-js-helpers/Boolean/isString')

isString([1, 2, 3])         //=> false

// extra arguments ignored:
isString(1, 'foo', 'bar')   //=> false

isString('foo')             //=> true

// extra argument ignored:
isString('foo', 3)          //=> true

isUndefinedBoolean

const isUndefined = require('@eluvio/elv-js-helpers/Boolean/isUndefined')
a → Boolean
Parameters
  • Anyx

    The value to test

  • Returns:Boolean

Returns true if passed undefined. Returns false if passed anything else

'use strict'
const isUndefined = require('@eluvio/elv-js-helpers/Boolean/isUndefined')

isUndefined()              //=> true

isUndefined(undefined)     //=> true

isUndefined(null)          //=> false

// extra argument ignored:
isUndefined(1, undefined)  //=> false

isUndefined('foo')         //=> false

// extra argument ignored:
isUndefined(undefined, 3)  //=> true

JustADT

const Just = require('@eluvio/elv-js-helpers/ADT/Just')
a → Just a
Parameters
  • Any(unnamed)

    The value to wrap in a Just

  • Returns:Maybe

Passthrough for the Just variety of the Maybe Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Maybe.html for more details.

Allows users of elv-js-helpers to create Just objects without adding the Crocks package as a dependency.

There are 2 kinds of Maybe objects, Just and Nothing, that wrap successful and failed value retrievals, respectively.

Maybe objects are useful for handling errors in Functional pipelines where a value may not be found.

Normally, one does not create generic Maybe object instances, but rather Just or Nothing instances.

'use strict'
const Just = require('@eluvio/elv-js-helpers/ADT/Just')

Just(42).inspect()    //=> 'Just 42'

kindValidation

const kind = require('@eluvio/elv-js-helpers/Validation/kind')
* → String
Parameters
  • Anyval

    The item to evaluate

  • Returns:String

    Name of the item's type

Modifies the kind-of package (Copyright © 2020, Jon Schlinkert, MIT License) by applying PascalCase capitalization to kinds that have corresponding PascalCase Javascript names

'use strict'
const kind = require('@eluvio/elv-js-helpers/Validation/kind')

kind(undefined)                //=> 'undefined'

kind(null)                     //=> 'null'

kind(true)                     //=> 'Boolean'

kind(Buffer.from(' '))         //=> 'Buffer'

kind(42)                       //=> 'Number'

kind('str')                    //=> 'String'

kind(arguments)                //=> 'arguments'

kind({})                       //=> 'Object'

kind(Object.create(null))      //=> 'Object'

kind(new Date())               //=> 'Date'

kind([1, 2, 3])                //=> 'Array'

kind(/foo/)                    //=> 'RegExp'

kind(new Error('error'))       //=> 'Error'

kind(function () {})           //=> 'Function'

kind(function * () {})         //=> 'GeneratorFunction'

kind(Symbol('str'))            //=> 'Symbol'

kind(new Map())                //=> 'Map'

kind(new WeakMap())            //=> 'WeakMap'

kind(new Set())                //=> 'Set'

kind(new WeakSet())            //=> 'WeakSet'

kind(new Int8Array())          //=> 'Int8Array'

kind(new Uint8Array())         //=> 'Uint8Array'

kind(new Uint8ClampedArray())  //=> 'Uint8ClampedArray'

kind(new Int16Array())         //=> 'Int16Array'

kind(new Uint16Array())        //=> 'Uint16Array'

kind(new Int32Array())         //=> 'Int32Array'

kind(new Uint32Array())        //=> 'Uint32Array'

kind(new Float32Array())       //=> 'Float32Array'

kind(new Float64Array())       //=> 'Float64Array'

lastFunctional

const last = require('@eluvio/elv-js-helpers/Functional/last')
[*] → * | undefined | EXCEPTION
String → String
Parameters
  • List(unnamed)

    an iterable list of elements

  • Returns:Any

    Last element of array or last character of string

Passthrough for Ramda's last function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns last element of a list or last character of a string, or undefined if there is no last element, and empty string if there is no last character

See also head, init, tail

'use strict'
const last = require('@eluvio/elv-js-helpers/Functional/last')

last([1, 2, 3, 4, 5])      //=> 5
last([1])                  //=> 1
last([])                   //=> undefined

last('abc')                //=> 'c'
last('a')                  //=> 'a'
last('')                   //=> ''

// NOTE: bad data types are ignored
last(0)                    //=> undefined

last({foo: 'bar'})         //=> undefined

// undefined will produce an exception
last(undefined)            //=> EXCEPTION: 'Cannot read properties of undefined'

liftA2Functional

const liftA2 = require('@eluvio/elv-js-helpers/Functional/liftA2')
Applicative m => (a → b → c) → m a → m b → m c
λcurried function
Parameters
  • function(unnamed)

    The 2-input curried function to lift

  • Returns:function

    The lifted function

Passthrough for the liftA2() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/helpers.html#lifta2 for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Lifting converts a function that works with 'normal' values as inputs and outputs and converts it into a function that works with values that are wrapped in a Functional data type (ADT) like Ok, Err, List, and Pair. The converted function will also return a value wrapped in a Functional data type.

This adapts the function to be able to compose into Functional workflows, making it easier to add things like input validation, error collection, and asynchronous event handling to the function cleanly.

liftA2 specifically converts 2-input curried functions.

'use strict'
const liftA2 = require('@eluvio/elv-js-helpers/Functional/liftA2')

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')
const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

// define a function that takes and returns 'normal' values:
const mult = (a, b) => a * b

mult(42, 42)                                              //=> 1764

// convert function 'mult' into one that works with values wrapped in Functional data types
const liftedMult = liftA2(curry(mult))

// create a wrapped good input
const okObject = Ok(42)

// create 2 wrapped errors indicating input failures:

// non-array input automatically converted to single element array
const errObject1 = Err('failed to obtain first input')

const errObject2 = Err(['failed to obtain second input'])

const goodResult = liftedMult(okObject, okObject)
goodResult.inspect()                                      //=> 'Ok 1764'

resultToPOJO(goodResult)                                  //=> {ok: true, value: 1764}

// call lifted function using 1 bad input:

const badResult1 = liftedMult(errObject1, okObject)
resultToPOJO(badResult1).ok                               //=> false
resultToPOJO(badResult1).errMsgs                          //=> ['failed to obtain first input']

const badResult2 = liftedMult(okObject, errObject2)
resultToPOJO(badResult2).ok                               //=> false
resultToPOJO(badResult2).errMsgs                          //=> ['failed to obtain second input']

// call lifted function using 2 bad inputs:

const badResult3 = liftedMult(errObject1, errObject2)
resultToPOJO(badResult3).ok                               //=> false
resultToPOJO(badResult3).errMsgs                          //=> ['failed to obtain first input', 'failed to obtain second input']

dumpJSON(resultToPOJO(badResult3))                        //=> OUTPUT: `{
                                                          //              "ok": false,
                                                          //              "errMsgs": [
                                                          //                "failed to obtain first input",
                                                          //                "failed to obtain second input"
                                                          //              ],
                                                          //              "errors": [
                                                          //                "failed to obtain first input",
                                                          //                "failed to obtain second input"
                                                          //              ]
                                                          //            }`

// liftA2 itself is curried, it can be called with 1-3 arguments as desired. If called with 3 arguments, it will
// immediately return the final result instead of returning a function.
liftA2(curry(mult), okObject, okObject).inspect()         //=> 'Ok 1764'

liftA2JoinFunctional

const liftA2Join = require('@eluvio/elv-js-helpers/Functional/liftA2Join')
Function → Function
λcurried function
Parameters
  • function(unnamed)

    A function which takes 2 'normal' values and returns a wrapped value (e.g. a Crocks Result)

  • Returns:function

    New function which takes 2 wrapped values and returns a wrapped value

Converts a function which accepts 2 'normal' values and returns a wrapped value (i.e. an ADT) into a function that takes 2 wrapped values and returns a wrapped value.

This is similar to the liftA2 function, except that it avoids adding an extra layer of wrapping to the returned value.

NOTE: The original function must be curried.

Note that the wrapper type of the inputs must be the same as the wrapper type returned by the function.

For example, if the original function returns a Maybe, then the inputs fed into the converted function must also be Maybes (i.e. Just or Nothing)

If the original function returns a Result, then the inputs fed into the converted function must also be Results (i.e. Ok or Err)

'use strict'
const liftA2Join = require('@eluvio/elv-js-helpers/Functional/liftA2Join')

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

// define a function that accepts 'normal' types as inputs and returns a wrapped type (an ADT)
const div = curry(
  (x, y) => y === 0 ?
    Err(['division by zero']) :
    Ok(x / y)
)

// convert into a function that accepts wrapped types as inputs instead (and still returns a wrapped type)
const divWrapped = liftA2Join(div)

divWrapped(
  Ok(42),
  Ok(2)
).inspect()                          //=> 'Ok 21'

divWrapped(
  Ok(42),
  Ok(0)
).inspect()                          //=> 'Err [ "division by zero" ]'

divWrapped(
  Err(['failed to read x']),
  Ok(0)
).inspect()                          //=> 'Err [ "failed to read x" ]'

divWrapped(
  Ok(42),
  Err(['failed to read y'])
).inspect()                          //=> 'Err [ "failed to read y" ]'

divWrapped(
  Err(['failed to read x']),
  Err(['failed to read y'])
).inspect()                          //=> 'Err [ "failed to read x", "failed to read y" ]'

liftA3Functional

const liftA3 = require('@eluvio/elv-js-helpers/Functional/liftA3')
Applicative m => (a → b → c → d) → m a → m b → m c → m d
λcurried function
Parameters
  • function(unnamed)

    The 3-input curried function to lift

  • Returns:function

    The lifted function

Passthrough for the liftA3() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/helpers.html#lifta3 for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Lifting converts a function that works with 'normal' values as inputs and outputs and converts it into a function that works with values that are wrapped in a Functional data type (ADT) like Ok, Err, List, and Pair. The converted function will also return a value wrapped in a Functional data type.

This adapts the function to be able to compose into Functional workflows, making it easier to add things like input validation, error collection, and asynchronous event handling to the function cleanly.

liftA3 specifically converts 3-input curried functions.

'use strict'
const liftA3 = require('@eluvio/elv-js-helpers/Functional/liftA3')

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')
const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

// define a function that takes and returns 'normal' values:
const mult3 = (a, b, c) => a * b * c

mult3(42, 42, 42)                                               //=> 74088

// convert function 'mult3' into one that works with values wrapped in Functional data types:
const liftedMult3 = liftA3(curry(mult3))

// create a wrapped good input
const okObject = Ok(42)


// create 2 wrapped errors indicating input failures:

// non-array input automatically converted to single element array
const errObject1 = Err('failed to obtain first input')

const errObject2 = Err(['failed to obtain second input'])

const goodResult = liftedMult3(okObject, okObject, okObject)
goodResult.inspect()                                              //=> 'Ok 74088'

resultToPOJO(goodResult)                                          //=> {ok: true, value: 74088}

// call lifted function using 1 bad input:

const badResult1 = liftedMult3(errObject1, okObject, okObject)
resultToPOJO(badResult1).ok                                       //=> false
resultToPOJO(badResult1).errMsgs                                  //=> ['failed to obtain first input']

const badResult2 = liftedMult3(okObject, errObject2, okObject)
resultToPOJO(badResult2).ok                                       //=> false
resultToPOJO(badResult2).errMsgs                                  //=> ['failed to obtain second input']

// call lifted function using 2 bad inputs:

const badResult3 = liftedMult3(errObject1, errObject2, okObject)
resultToPOJO(badResult3).ok                                       //=> false
resultToPOJO(badResult3).errMsgs                                  //=> ['failed to obtain first input', 'failed to obtain second input']

dumpJSON(resultToPOJO(badResult3))                                //=> OUTPUT: `{
                                                                  //              "ok": false,
                                                                  //              "errMsgs": [
                                                                  //                "failed to obtain first input",
                                                                  //                "failed to obtain second input"
                                                                  //              ],
                                                                  //              "errors": [
                                                                  //                "failed to obtain first input",
                                                                  //                "failed to obtain second input"
                                                                  //              ]
                                                                  //            }`

// liftA3 itself is curried, it can be called with 1-4 arguments as desired. If called with 4 arguments, it will
// immediately return the final result instead of returning a function.
liftA3(curry(mult3), okObject, okObject, okObject).inspect()     //=> 'Ok 74088'

liftA3JoinFunctional

const liftA3Join = require('@eluvio/elv-js-helpers/Functional/liftA3Join')
Function → Function
λcurried function
Parameters
  • function(unnamed)

    A function which takes 3 'normal' values and returns a wrapped value (e.g. a Crocks Result)

  • Returns:function

    New function which takes 3 wrapped values and returns a wrapped value

Converts a function which accepts 3 'normal' values and returns a wrapped value (i.e. an ADT) into a function that takes 3 wrapped values and returns a wrapped value.

This is similar to the liftA3 function, except that it avoids adding an extra layer of wrapping to the returned value.

NOTE: The original function must be curried.

Note that the wrapper type of the inputs must be the same as the wrapper type returned by the function.

For example, if the original function returns a Maybe, then the inputs fed into the converted function must also be Maybes (i.e. Just or Nothing)

If the original function returns a Result, then the inputs fed into the converted function must also be Results (i.e. Ok or Err)

'use strict'
const liftA3Join = require('@eluvio/elv-js-helpers/Functional/liftA3Join')

const curry = require('@eluvio/elv-js-helpers/Functional/curry')
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

// define a function that accepts 'normal' types as inputs and returns a wrapped type (an ADT)
const div3 = curry(
  (x, y, z) => y === 0 || z === 0 ?
    Err(['division by zero']) :
    Ok(x / y / z)
)

// convert into a function that accepts wrapped types as inputs instead (and still returns a wrapped type)
const div3Wrapped = liftA3Join(div3)

div3Wrapped(
  Ok(42),
  Ok(3),
  Ok(2)
).inspect()                           //=> 'Ok 7'

div3Wrapped(
  Ok(42),
  Ok(0),
  Ok(2)
).inspect()                           //=> 'Err [ "division by zero" ]'

div3Wrapped(
  Err(['failed to read x']),
  Ok(0),
  Ok(2)
).inspect()                           //=> 'Err [ "failed to read x" ]'

div3Wrapped(
  Ok(42),
  Err(['failed to read y']),
  Ok(2)
).inspect()                           //=> 'Err [ "failed to read y" ]'

div3Wrapped(
  Err(['failed to read x']),
  Err(['failed to read y']),
  Err(['failed to read z'])
).inspect()                           //=> 'Err [ "failed to read x", "failed to read y", "failed to read z" ]'

ListADT

const List = require('@eluvio/elv-js-helpers/ADT/List')
* → List *
Parameters
  • Any(unnamed)

    The value to wrap in a List

  • Returns:List

Passthrough for the List Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to create List objects without adding the Crocks package as a dependency.

const List = require('@eluvio/elv-js-helpers/ADT/List')

const myList = List([1,2,3])

// List with 3 elements:
myList.inspect()                 //=> 'List [ 1, 2, 3 ]'

// Convert to Javascript array:
myList.toArray()                //=> [ 1, 2, 3 ]

// head() returns instance of the Crocks 'Maybe' ADT: if array is empty, returns Nothing, else returns Just
myList.head().inspect()         //=> 'Just 1'

// tail() returns an instance of Crocks 'Maybe' ADT, which wraps a List if there were at least 2 elements in original List
myList.tail().inspect()                   //=> 'Just List [ 2, 3 ]'

// List with 1 element, which itself is a 3-item array:
List([[1,2,3]]).inspect()                 //=> 'List [ [ 1, 2, 3 ] ]'

// List with 1 element:
List([42]).inspect()                      //=> 'List [ 42 ]'
List([42]).tail().inspect()                 //=> 'Nothing'

// Non-array input is treated as a single-element array:
List(42).inspect()                        //=> 'List [ 42 ]'

// List with 0 elements:
const emptyList = List([])
emptyList.inspect()                    //=> 'List [ ]'

// Instance of the Crocks 'Maybe' ADT, with no value
emptyList.head().inspect()                //=> 'Nothing'

listPushFunctional

const listPush = require('@eluvio/elv-js-helpers/Functional/listPush')
List → * → List
λcurried function
Parameters
  • Listlist

    A Crocks List object

  • Anyelement

    The item to add to end of list

  • Returns:List

    New Crocks List containing original list elements plus new element at end

Returns a new Crocks List object with new element added to end

'use strict'
const listPush = require('@eluvio/elv-js-helpers/Functional/listPush')

const List = require('@eluvio/elv-js-helpers/ADT/List')

listPush(List([1,2,3]), 4).inspect()    //=> 'List [ 1, 2, 3, 4 ]'

mapFunctional

const map = require('@eluvio/elv-js-helpers/Functional/map')
(a → b) → m a → m b
λcurried function
Parameters
  • function(unnamed)

    A curried function that takes a 'normal' value and returns a 'normal' value)

  • Object(unnamed)

    Instance of Functional data type to pass into function

  • Returns:*

    The wrapped result

Passthrough for the map() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Not to be confused with the map function from Ramda, although functionality is similar.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Provides a pointfree way to call .map() on a value wrapped in a Functional data type.

Given a curried function that takes a 'normal' value and returns another 'normal' value, map will convert it into a function that takes a wrapped value and returns a wrapped value.

'use strict'
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const map = require('@eluvio/elv-js-helpers/Functional/map')

// function has only one input, not need to curry
const double = a => a * 2

const ok21 = Ok(21)
const badNum = Err(['failed to read input'])

double(21)                          //=> 42

// double() does not know to unwrap value before use:
double(ok21)                        //=> NaN

// map() asks input wrapper to remove wrapping and pass value to function, and then re-wrap the return value
map(double, ok21).inspect()         //=> 'Ok 42'

// badNum ignores request to apply double()
map(double, badNum).inspect()       //=> 'Err [ "failed to read input" ]'

mapObjKeysFunctional

const mapObjKeys = require('@eluvio/elv-js-helpers/Functional/mapObjKeys')
((String, *, Object) → *) → Object → Object
λcurried function
Parameters
  • functionfn

    The function to execute to obtain new key

  • Objectobj

    The object to process

  • Returns:Object

Creates a new object with keys transformed by a function but values kept the same.

The function can have up to three inputs and will be passed current key, value, and the entire original object.

'use strict'
const mapObjKeys = require('@eluvio/elv-js-helpers/Functional/mapObjKeys')

const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')

const myObj = {
  firstname: "arthur",
  lastname: "dent",
  id: 42
}

// note that function can have fewer than 3 inputs if you don't need to use all of the parameters:
const keyPrefixer = key =>  `new_${key}`

const result = mapObjKeys(
  keyPrefixer,
  myObj
)

dumpJSON(result)         //=> OUTPUT: '{\n  "new_firstname": "arthur",\n  "new_lastname": "dent",\n  "new_id": 42\n}'

mapObjKVFunctional

const mapObjKV = require('@eluvio/elv-js-helpers/Functional/mapObjKV')
((String, *, Object) → *) → ((*, String, Object) → *) → Object → Object
λcurried function
Parameters
  • functionkeyFn

    The function to execute to obtain new key

  • functionvalFn

    The function to execute to obtain new value

  • Objectobj

    The object to process

  • Returns:Object

Creates a new object with top level keys and values transformed by separate functions.

The key transformation function can have up to three inputs and will be passed current KEY, current VALUE, and the entire original object.

The value transformation function can have up to three inputs and will be passed current VALUE, current KEY, and the entire original object.

'use strict'
const mapObjKV = require('@eluvio/elv-js-helpers/Functional/mapObjKV')

const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')

const myObj = {
  firstname: "arthur",
  lastname: "dent",
  id: 42
}

// note that function can have fewer than 3 inputs if you don't need to use all of the parameters:
const keyPrefixer = key =>  `new_${key}`

// note that function can have fewer than 3 inputs if you don't need to use all of the parameters:
const nameCapitalizer = (val, key) =>  key.endsWith('name')
  ? val.charAt(0).toUpperCase() + val.slice(1)
  : val

const result = mapObjKV(
  keyPrefixer,
  nameCapitalizer,
  myObj
)

dumpJSON(result)         //=> OUTPUT: '{\n  "new_firstname": "Arthur",\n  "new_lastname": "Dent",\n  "new_id": 42\n}'

mapObjValuesFunctional

const mapObjValues = require('@eluvio/elv-js-helpers/Functional/mapObjValues')
((*, String, Object) → *) → Object → Object
λcurried function
Parameters
  • functionfn

    The function to execute to obtain new value

  • Objectobj

    The object to process

  • Returns:Object

Creates a new object with same keys as original object but with values transformed by specified function.

The function can have up to three inputs and will be passed current value, key, and the entire original object.

'use strict'
const mapObjValues = require('@eluvio/elv-js-helpers/Functional/mapObjValues')

const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')

const myObj = {
  firstname: "arthur",
  lastname: "dent",
  id: 42
}

// note that function can have fewer than 3 inputs if you don't need to use all of the parameters:
const nameCapitalizer = (val, key) =>  key.endsWith('name')
  ? val.charAt(0).toUpperCase() + val.slice(1)
  : val

const result = mapObjValues(
  nameCapitalizer,
  myObj
)

dumpJSON(result)         //=> OUTPUT: '{\n  "firstname": "Arthur",\n  "lastname": "Dent",\n  "id": 42\n}'

mapWithIndexFunctional

const mapWithIndex = require('@eluvio/elv-js-helpers/Functional/mapWithIndex')
((*, Integer) → *) → Array → Array
λcurried function
Parameters
  • function(unnamed)

    The function to apply to each (element, index) pair

  • Array(unnamed)

    The array to iterate over

  • Returns:Array

Iterates over an array and passes (element, index) pair to supplied function to generate new array

'use strict'
const mapWithIndex = require('@eluvio/elv-js-helpers/Functional/mapWithIndex')

mapWithIndex((e,i) => `${e}-${i}`, ['a', 'b', 'c']) //=> ['a-0', 'b-1', 'c-2']

// function is curried: call with just 1 arg to obtain a narrower function
const addIndexSuffix = mapWithIndex((e,i) => `${e}-${i}`)

addIndexSuffix(['a', 'b', 'c'])     //=> ['a-0', 'b-1', 'c-2']

matchesRegexBoolean

const matchesRegex = require('@eluvio/elv-js-helpers/Boolean/matchesRegex')
RegExp → * → Boolean
λcurried function
Parameters
  • RegExpre

    the regexp to use to test

  • Anyvalue

    the value to test

  • Returns:Boolean

Returns true if second input is matches regex in first input, false otherwise.

If called with fewer than 2 arguments, will return a partially applied function

'use strict'
const matchesRegex = require('@eluvio/elv-js-helpers/Boolean/matchesRegex')

matchesRegex(/a/, 'abc')             //=> true

matchesRegex(/a/, 'def')             //=> false

matchesRegex(/a/, 0)                 //=> false

// function is curried: can call with fewer params to obtain a narrower function
const isThreeDigitNum = matchesRegex(/^[0-9]{3}$/)

isThreeDigitNum('123')               //=> true

// Javascript does automatic type conversion in this case
isThreeDigitNum(123)                 //=> true

isThreeDigitNum('foo')               //=> false

isThreeDigitNum('001')               //=> true

isThreeDigitNum(1)                   //=> false

mergeRightFunctional

const mergeRight = require('@eluvio/elv-js-helpers/Functional/mergeRight')
Object → Object → Object
λcurried function

Modified passthrough for Ramda's mergeRight function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Creates a new object with the top-level properties of the first object merged with the top-level properties from the second object. If a top-level key exists in both objects, the value from the first object will be replaced by the value from the second object.

Original object's constructor used to process merged data in order to preserve ObjectModel constraints on non-primitive models

'use strict'
const mergeRight = require('@eluvio/elv-js-helpers/Functional/mergeRight')

const defaults = {
  children: ["DefaultChild1", "DefaultChild2"],
  name: "Anonymous",
}

const moreData = {
  age: 35,
  children: ["Charlie"]
}

mergeRight(defaults, moreData)                //=> {age: 35, children: ["Charlie"], name: "Anonymous"}

// function is curried: can call with fewer params to obtain a more specific function:

const ensureNameAndChildren = mergeRight(defaults)

ensureNameAndChildren({})      //=> {children: ["DefaultChild1", "DefaultChild2"], name: "Anonymous"}

negateFunctional

const negate = require('@eluvio/elv-js-helpers/Functional/negate')
(a → Boolean) → (a → Boolean)
Parameters
  • function(unnamed)

    A function that takes one input and returns a Boolean

  • Returns:function

    A function that returns logically inverted output of the original function

Renamed passthrough for the not() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Takes a 1-input function and returns a negated version of the function, which will return false where the original function returned true, and true where the original function returned false.

NOTE: This is not equivalent to using the Javascript NOT (!) operator, it returns a new function rather than returning negated result. It also is not suitable for negating functions with more than 1 input, as it will interfere with currying and the additional arguments.

'use strict'
const negate = require('@eluvio/elv-js-helpers/Functional/negate')

const isEmpty = a => a.length === 0

const isNotEmpty = negate(isEmpty)

isNotEmpty('foo')         //=> true

isNotEmpty('')            //=> false

isNotEmpty([])            //=> false

isNotEmpty([1, 2, 3])     //=> true

isNotEmpty(undefined)     //=> EXCEPTION: "Cannot read properties of undefined (reading 'length')"

neighborsPassBoolean

const neighborsPass = require('@eluvio/elv-js-helpers/Boolean/neighborsPass')
((a, a) → Boolean) → Array → Boolean
λcurried function
Parameters
  • functioncheckFn

    2-input function that returns true if the inputs pass check, false otherwise

  • Arrayarray

    Array or other iterable with elements to check

  • Returns:Boolean

Returns true if all pairs of neighbors in array return true when fed into checkFn.

Can be used to verify ordering, e.g. if checkFn is (x,y) => x <= y then array must be in ascending order.

'use strict'
const neighborsPass = require('@eluvio/elv-js-helpers/Boolean/neighborsPass')

const xGTEy = (x,y) => x <= y

neighborsPass(xGTEy, [1, 2, 2, 3])   //=> true

// single element, has no pairs to check:
neighborsPass(xGTEy, [1])            //=> true

neighborsPass(xGTEy, [3, 2, 2, 1])   //=> false

// strings support indexed access via []:
neighborsPass(xGTEy, 'abcde')        //=> true

// non-array, has no pairs to check:
neighborsPass(xGTEy, 5)              //=> true

// function is curried: call with 1 arg to obtain a narrower function
const isOrdered = neighborsPass(xGTEy)

isOrdered([1, 2, 2, 3])                    //=> true

isOrdered([1])                             //=> true

isOrdered([3, 2, 2, 1])                    //=> false

// strings support indexed access via []:
isOrdered('abcde')                         //=> true

// non-array, has no pairs to check:
isOrdered(5)                               //=> true

NonBlankStrModelModel

const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

NonBlankStrModel('foo') //=> 'foo'

NonBlankStrModel('  ')  //=> EXCEPTION: 'Value must not be a blank string (got: "  ")'

NonBlankStrModel(42)    //=> EXCEPTION: 'expecting String, got Number 42'

NonNegativeIntModelModel

const NonNegativeIntModel = require('@eluvio/elv-js-helpers/Model/NonNegativeIntModel')
* → * | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Integer

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const NonNegativeIntModel = require('@eluvio/elv-js-helpers/Model/NonNegativeIntModel')

NonNegativeIntModel(42)    //=> 42

NonNegativeIntModel(0)     //=> 0

NonNegativeIntModel(4.2)   //=> EXCEPTION: 'Value must be an integer (got: 4.2)'

NonNegativeIntModel(-1)    //=> EXCEPTION: 'Value must be >= 0 (got: -1)'

NonNegativeIntModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

NonNegativeIntModel(Infinity) //=> EXCEPTION: 'Value must be an integer (got: Infinity)'

NonNegativeIntModel(-Infinity) //=> EXCEPTION: 'Value must be an integer (got: -Infinity)'

NonNegativeNumModelModel

const NonNegativeNumModel = require('@eluvio/elv-js-helpers/Model/NonNegativeNumModel')
* → * | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const NonNegativeNumModel = require('@eluvio/elv-js-helpers/Model/NonNegativeNumModel')

NonNegativeNumModel(42)        //=> 42

NonNegativeNumModel(0)         //=> 0

NonNegativeNumModel(-1)        //=> EXCEPTION: 'Value must be >= 0 (got: -1)'

NonNegativeNumModel('foo')     //=> EXCEPTION: 'expecting Number, got String "foo"'

NonNegativeNumModel(Infinity)  //=> Infinity

NonNegativeNumModel(-Infinity) //=> EXCEPTION: 'Value must be >= 0 (got: -Infinity)'

NothingADT

const Nothing = require('@eluvio/elv-js-helpers/ADT/Nothing')
() → Nothing
Parameters
  • Returns:Maybe

Passthrough for the Nothing variety of the Maybe Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Maybe.html for more details.

Allows users of elv-js-helpers to create Nothing objects without adding the Crocks package as a dependency.

There are 2 kinds of Maybe objects, Just and Nothing, that wrap successful and failed value retrievals, respectively.

Maybe objects are useful for handling errors in Functional pipelines where a value may not be found.

Normally, one does not create generic Maybe object instances, but rather Just or Nothing instances.

'use strict'
const Nothing = require('@eluvio/elv-js-helpers/ADT/Nothing')

Nothing().inspect()    //=> 'Nothing'

Nothing(42).inspect()    //=> 'Nothing'

nowConversion

const now = require('@eluvio/elv-js-helpers/Conversion/now')
() → Date
Parameters
  • Returns:Date

Returns current datetime as a Javascript Date

'use strict'
const now = require('@eluvio/elv-js-helpers/Datetime/now')

const isGT = require('@eluvio/elv-js-helpers/Boolean/isGT')
const kind = require('@eluvio/elv-js-helpers/Validation/kind')

const currentDatetime = now()

kind(currentDatetime)                            //=> 'Date'

// later than 2022-12-02T16:53:20Z:
isGT(1670000000000, currentDatetime.valueOf())   //=> true

NumberModelModel

const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel')
* → Number | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is a Javascript Number

If input passes validation, will return the input.

Throws an exception if passed in an invalid value. Infinity is accepted, but NaN is not.

'use strict'
const NumberModel = require('@eluvio/elv-js-helpers/Model/NumberModel')

NumberModel(42)        //=> 42

NumberModel('foo')     //=> EXCEPTION: 'expecting Number, got String "foo"'

NumberModel(Infinity)  //=> Infinity

NumberModel(-Infinity) //=> -Infinity

// Error message for NaN is not the greatest:
NumberModel(NaN)      //=> EXCEPTION: 'expecting Number, got Number NaN'

NumZeroToOneModelModel

const NumZeroToOneModel = require('@eluvio/elv-js-helpers/Model/NumZeroToOneModel')
* → Number | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const NumZeroToOneModel = require('@eluvio/elv-js-helpers/Model/NumZeroToOneModel')

NumZeroToOneModel(0)     //=> 0

NumZeroToOneModel(0.5)   //=> 0.5

NumZeroToOneModel(1)     //=> 1

NumZeroToOneModel(42)    //=> EXCEPTION: 'Value must be >= 0 and <= 1 (got: 42)'

NumZeroToOneModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

NumZeroToOneXModelModel

const NumZeroToOneXModel = require('@eluvio/elv-js-helpers/Model/NumZeroToOneXModel')
* → Number | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const NumZeroToOneXModel = require('@eluvio/elv-js-helpers/Model/NumZeroToOneXModel')

NumZeroToOneXModel(0)     //=> 0

NumZeroToOneXModel(0.5)   //=> 0.5

NumZeroToOneXModel(1)     //=> EXCEPTION: 'Value must be >= 0 and < 1 (got: 1)'

NumZeroToOneXModel(42)    //=> EXCEPTION: 'Value must be >= 0 and < 1 (got: 42)'

NumZeroToOneXModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

objBadKeyValidation

const objBadKey = require('@eluvio/elv-js-helpers/Validation/objBadKey')
Model → Object → String | undefined
λcurried function
Parameters
  • ModelkeyModel

    The Model to check keys against

  • Returns:String
    • The bad key if found, undefined otherwise

Iterates over object properties and returns first property name (key) where passesModelCheck(keyModel) returns false

Returns undefined if all keys are valid.

'use strict'
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const objBadKey = require('@eluvio/elv-js-helpers/Validation/objBadKey')

objBadKey(NonBlankStrModel, {foo:3})  //=> undefined

objBadKey(NonBlankStrModel, {' ':3})  //=> ' '

// function is curried: call with fewer params to obtain a narrower function
const findBlankKey = objBadKey(NonBlankStrModel)

findBlankKey({foo:3})  //=> undefined

findBlankKey({' ':3})  //=> ' '

objBadValValidation

const objBadVal = require('@eluvio/elv-js-helpers/Validation/objBadVal')
Model → Object → [k, v] | undefined
λcurried function
Parameters
  • ModelvalueModel

    The Model to check values against

  • Returns:Array
    • The key/value pair for the bad value, or undefined if all values valid

Iterates over object values and returns 2-element array [key, value] pair for first value found that does not validate against Model

Returns undefined if all values are valid.

'use strict'
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const objBadVal = require('@eluvio/elv-js-helpers/Validation/objBadVal')

objBadVal(NonBlankStrModel, {foo: 'bar'})   //=> undefined

objBadVal(NonBlankStrModel, {foo: ' '})     //=> ['foo', ' ']

objBadVal(NonBlankStrModel, {foo: 42})      //=> ['foo', 42]

// function is curried: call with fewer params to obtain a narrower function
const findBlankVal = objBadVal(NonBlankStrModel)

findBlankVal({foo: 'bar'})    //=> undefined

findBlankVal({foo: ' '})      //=> ['foo', ' ']

ObjectModelModel

const ObjectModel = require('@eluvio/elv-js-helpers/Model/ObjectModel')
* → Object | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is a Javascript Object

If input passes validation, will return the input.

Throws an exception if passed in an invalid value.

'use strict'
const ObjectModel = require('@eluvio/elv-js-helpers/Model/ObjectModel')

ObjectModel({foo: "bar"})    //=> {foo: "bar"}

ObjectModel('foo') //=> EXCEPTION: 'expecting Object, got String "foo"'

objFromEntriesConversion

const objFromEntries = require('@eluvio/elv-js-helpers/Conversion/objFromEntries')
[[String *]] → Object
Parameters
  • Arrayarr

    Array of 2-element arrays each containing an attribute name and value

  • Returns:Object

Javascript's built-in Object.fromEntries() function.

Creates an object from a list of key/value pairs.

Not to be confused with fromPairs(), which takes a Crocks List of Pairs.

See also fromPairs

'use strict'
const objFromEntries = require('@eluvio/elv-js-helpers/Conversion/objFromEntries')

const kvPairs = [['a', 1], ['b',[['c', 3],['d', 4]]]]

objFromEntries(kvPairs)     //=> { a: 1, b: [['c', 3],['d', 4]] }

objHasKeyBoolean

const objHasKey = require('@eluvio/elv-js-helpers/Boolean/objHasKey')
String → a → Boolean
λcurried function
Parameters
  • stringkey

    The key to check for

  • Anyx

    The value to test

  • Returns:Boolean

Returns true if item is an object with the specified key. Returns false otherwise

'use strict'
const objHasKey = require('@eluvio/elv-js-helpers/Boolean/objHasKey')

objHasKey('foo', {foo: 'bar'})   //=> true

objHasKey('bar', {foo: 'bar'})   //=> false

objHasKey('foo', [1, 2, 3])      //=> false

objHasKey('1', {1: 42})          //=> true

objHasKey(1, {1: 42})            //=> false

// function is curried, pass less than full number of arguments to obtain another narrower function
const hasFoo = objHasKey('foo')

hasFoo({foo: 'bar'})          //=> true

hasFoo({bar: 'baz'})          //=> false

objToEntriesConversion

const objToEntries = require('@eluvio/elv-js-helpers/Conversion/objToEntries')
Object → [[String *]]
Parameters
  • Objectobj

    Object to convert

  • Returns:Array

    Array of 2-element arrays each containing an attribute name and value

Javascript's built-in Object.toEntries() function.

Creates an array of key/value pairs from an object.

Not to be confused with toPairs(), which returns a Crocks List of Pairs.

Provided for use in function composition.

See also toPairs

'use strict'
const objToEntries = require('@eluvio/elv-js-helpers/Conversion/objToEntries')

const obj = {a: 1, b: {c: 3, d:4}}

objToEntries(obj)     //=> [['a', 1], ['b', {c: 3, d:4}]]

OkADT

const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')
a → Ok a
Parameters
  • Any(unnamed)

    The value to wrap in an Ok

  • Returns:Result

Passthrough for the Ok variety of the Result Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Result.html for more details.

Allows users of elv-js-helpers to create Ok objects without adding the Crocks package as a dependency.

There are 2 kinds of Result objects, Ok and Err, that wrap successful and failed computations, respectively.

Result objects are useful for handling errors in Functional pipelines and can collect multiple errors from various branches of a workflow.

Normally, one does not create generic Result object instances, but rather Ok or Err instances.

'use strict'
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

Ok(42).inspect()    //=> 'Ok 42'

omitFunctional

const omit = require('@eluvio/elv-js-helpers/Functional/omit')
[ String ] → Object → Object
λcurried function
Parameters
  • Array.<string>(unnamed)

    A list of keys to omit

  • Object(unnamed)

    An object to process

  • Returns:Object

    A shallow copy of object with specified keys removed (as well as any keys pointing to undefined)

Passthrough for the omit() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Takes an array of strings and an object and returns a shallow copy of object with matching keys removed, as well as any keys pointing to undefined.

'use strict'
const omit = require('@eluvio/elv-js-helpers/Functional/omit')

const myObject = {foo: "f", bar: "b"}

omit(['foo'], myObject) //=> {bar: 'b'}

orFunctional

const or = require('@eluvio/elv-js-helpers/Functional/or')
(a → Boolean | Pred a) → (a → Boolean | Pred a) → a → Boolean
λcurried function
Parameters
  • function(unnamed)

    First function that returns a Boolean

  • function(unnamed)

    Second function that returns a Boolean

  • Returns:function

    Function which takes input, passes to both input functions, and then combines return values with logical OR

Passthrough for the or() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Given two predicate functions (a -> Boolean), returns a function that combines the two using logical OR.

'use strict'
const or = require('@eluvio/elv-js-helpers/Functional/or')

const isEven = x => (x % 2) === 0
const isNegative = x => x < 0

const isNegOrEven = or(isEven, isNegative)

isNegOrEven(3)         //=> false
isNegOrEven(2)         //=> true
isNegOrEven(-3)        //=> true

PairADT

const Pair = require('@eluvio/elv-js-helpers/ADT/Pair')
(a, b) → Pair a b
Parameters
  • Any(unnamed)

    The first (left) value to wrap in a Pair

  • Any(unnamed)

    The second (right) value to wrap in a Pair

  • Returns:Pair

Passthrough for the Pair Crocks Algebraic Data Type (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Pair.html for more details.

Allows users of elv-js-helpers to create Pair objects without adding the Crocks package as a dependency.

Pair objects are useful for creating Functional pipelines where an original value and a derived value both need to be carried forward. They can also be useful for manipulating key-value pairs, or any situation where a value needs an accompanying tag.

'use strict'
const Pair = require('@eluvio/elv-js-helpers/ADT/Pair')

const p = Pair(1,2)
p.inspect()           //=> 'Pair( 1, 2 )'

p.fst()                //=> 1

p.snd()                //=> 2

Pair(42)               //=> EXCEPTION: 'Pair: Must provide a first and second value'

parseUTCStrConversion

const parseUTCStr = require('@eluvio/elv-js-helpers/Conversion/parseUTCStr')
String → Date
Parameters
  • StringutcString

    The UTC timestamp to convert

  • Returns:Date

Converts a string in UTC format (e.g. '2022-01-01T14:00:00Z' or '2022-01-01T14:00:00.0000Z') to a Javascript Date

Returns a NaN date if string is an invalid date or is not in format: YYYY-MM-DDThh:mm:ss[.s...]Z

Use utcStrToDate or UTCStrModel instead to generate an error on invalid date strings.

See also utcStrToDate

'use strict'
const dateObject = parseUTCStr('2022-01-01T14:00:00Z')
dateObject.valueOf()                                  //=> 1641045600000

const dateObjectMilliseconds = parseUTCStr('2022-01-01T14:00:00.123Z')
dateObjectMilliseconds.valueOf()                     //=> 1641045600123

// Strings containing bad datetime return Date object containing NaN
const badDate = parseUTCStr('2022-99-01T14:00:00Z')
badDate.valueOf()                                     //=> NaN

// Non-strings return Date object containing NaN
const nonStringDate = parseUTCStr(42)
nonStringDate.valueOf()                               //=> NaN

passesModelCheckBoolean

const passesModelCheck = require('@eluvio/elv-js-helpers/Boolean/passesModelCheck')
Model → * → Boolean
λcurried function
Parameters
  • ModelModel

    The Model to test against

  • Anyinput

    The value to test

  • Returns:Boolean

Returns true if the specified Model successfully validates an input, false otherwise.

Used when the caller does not care about the details of why the input failed validation.

'use strict'
const passesModelCheck = require('@eluvio/elv-js-helpers/Boolean/passesModelCheck')

const PositiveIntModel = require('@eluvio/elv-js-helpers/Model/PositiveIntModel')

passesModelCheck(PositiveIntModel, -1) //=> false

// function is curried: call with just first param to obtain a narrower function
const isPositiveInt = passesModelCheck(PositiveIntModel)

isPositiveInt(1)     //=> true

isPositiveInt(0)     //=> false

isPositiveInt('foo') //=> false

passesObjKeyCheckBoolean

const passesObjKeyCheck = require('@eluvio/elv-js-helpers/Boolean/passesObjKeyCheck')
Model → * → Boolean
λcurried function
Parameters
  • ModelkeyModel

    the Model to check keys against

  • Anyobj

    The item to check

  • Returns:Boolean

Returns

  • true if the input is an object and all the object's keys are valid instances of the specified Model OR the input is not a Javascript object
  • false if the input IS a Javascript object AND has a key (property name) that violates specified Model

Intended for use in an ObjectModel assertion.

Note that true is returned for non-object inputs.

If called with fewer than 2 arguments, will return a partially applied function

'use strict'
const passesObjKeyCheck = require('@eluvio/elv-js-helpers/Boolean/passesObjKeyCheck')

const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

passesObjKeyCheck(NonBlankStrModel, {' ': 42})   //=> false

passesObjKeyCheck(NonBlankStrModel, {foo: 42})   //=> true

// test input not an object, check skipped:
passesObjKeyCheck(NonBlankStrModel, 3)           //=> true

// function is curried: call with fewer params to obtain a narrower function

const hasNoBlankKeys = passesObjKeyCheck(NonBlankStrModel)

hasNoBlankKeys({' ': 42})                        //=> false

hasNoBlankKeys({foo: 42})                        //=> true

// test input not an object, check skipped:
hasNoBlankKeys(3)                                //=> true

passesObjValCheckBoolean

const passesObjValCheck = require('@eluvio/elv-js-helpers/Boolean/passesObjValCheck')
Model → * → Boolean
λcurried function
Parameters
  • ModelvalueModel

    the Model to check values against

  • Anyobj

    The item to check

  • Returns:Boolean

Returns

  • true if the input is an object and all the object's values are valid instances of the specified Model OR the input is not a Javascript object
  • false if the input IS a Javascript object AND has a value that violates specified Model

Intended for use in an ObjectModel assertion.

Note that true is returned for non-object inputs.

If called with fewer than 2 arguments, will return a partially applied function

'use strict'
const passesObjValCheck = require('@eluvio/elv-js-helpers/Boolean/passesObjValCheck')

const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

passesObjValCheck(NonBlankStrModel, {foo: ' '})   //=> false

passesObjValCheck(NonBlankStrModel, {foo: 'bar'}) //=> true

// value not a non-blank string:
passesObjValCheck(NonBlankStrModel, {foo: 42})    //=> false

// test input not an object, check skipped:
passesObjValCheck(NonBlankStrModel, 3)            //=> true

// function is curried: call with fewer params to obtain a narrower function

const allValsNonBlankString = passesObjValCheck(NonBlankStrModel)

allValsNonBlankString({foo: ' '})                 //=> false

allValsNonBlankString({foo: 'bar'})               //=> true

// value not a non-blank string:
allValsNonBlankString({foo: 42})                  //=> false

// test input not an object, check skipped:
allValsNonBlankString(3)                          //=> true

pickFunctional

const pick = require('@eluvio/elv-js-helpers/Functional/pick')
[String] → Object → Object
λcurried function
Parameters
  • Array.<String>(unnamed)

    A list of keys to include

  • Object(unnamed)

    The object to copy from

  • Returns:Object

    A shallow copy of the original object with only the specified keys

Passthrough for the pick() Crocks helper function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Not to be confused with the pick function from Ramda, although functionality is similar.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Accepts a list of keys and an object then returns a partial shallow copy of the object with only the specified keys.

'use strict'
const pick = require('@eluvio/elv-js-helpers/Functional/pick')

const person = {
  firstName: 'Arthur',
  middleName: 'Philip',
  lastName:  'Dent',
  species: 'Human'
}

pick(['firstName', 'lastName'], person)    //=>  {firstName: 'Arthur', lastName:  'Dent'}

// function is curried, call with just first param to return a narrower function:
const speciesPicker = pick(['species'])

speciesPicker(person)                      //=>  {species: 'Human'}

pickByFunctional

const pickBy = require('@eluvio/elv-js-helpers/Functional/pickBy')
((v, k) → Boolean) → {k: v} → {k: v}
λcurried function
Parameters
  • functiontestFn

    function that accepts two args (value, key) and returns true or false

  • Objectobj

    array of arrays or objects to pluck property or element from

  • Returns:Object

    Object containing only the keys where testFn(value, key) returned true

Passthrough for Ramda's pickBy function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a new object with the keys selected by a test function called with value/key pairs.

'use strict'
const pickBy = require('@eluvio/elv-js-helpers/Functional/pickBy')

const valueIsEven = (v, k) => v % 2 === 0

const obj = {a: 1, b: 2, c: 3, d:4}

pickBy(valueIsEven, obj)    //=> {b:2, d:4}

// function is curried: call with just first param to obtain a more specialized function
const evenValuesOnly = pickBy(valueIsEven)

evenValuesOnly(obj)        //=> {b:2, d:4}

pipeFunctional

const pipe = require('@eluvio/elv-js-helpers/Functional/pipe')
((a → b), …, (y → z)) → a → z
λcurried function
Parameters
  • function(unnamed)

    Two or more curried functions to compose in left-to-right order

  • Returns:function

    The composed function

Passthrough for the pipe() Crocks helper function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/functions/helpers.html#pipe for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Composes functions in left to right order (which is generally more readable than the right-to-left order used by compose) and returns a new function.

'use strict'
const pipe = require('@eluvio/elv-js-helpers/Functional/pipe')

// function has only one input, no need to curry
const trim = str => str.trim()

// function has only one input, not need to curry
const capitalizeFirst = str => str.charAt(0).toUpperCase() + str.slice(1)

const trimAndCapitalize = pipe(trim, capitalizeFirst)

trimAndCapitalize('   foo  ')    //=> 'Foo'

pipeChainableFunctional

const pipeChainable = require('@eluvio/elv-js-helpers/Functional/pipeChainable')
Chain m => ((a → m b), …, (y → m z)) → a → m z
λcurried function
Parameters
  • Any(unnamed)

    Two or more chainable operations

  • Returns:ADT

    A chainable ADT

Renamed and modified version of the pipeK() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows composing functional workflows that would normally require use of .chain().

'use strict'
const pipeChainable = require('@eluvio/elv-js-helpers/Functional/pipeChainable')

// https://api.dictionaryapi.dev/api/v2/entries/en/aardvark
// https://oeis.org/search?q=id:A000040&fmt=json

pluckFunctional

const pluck = require('@eluvio/elv-js-helpers/Functional/pluck')
Number | String → List → [*] | EXCEPTION
λcurried function
Parameters
  • IntegerpropOrIndex

    the property or array element index to pull from each item in list

  • Arrayx

    array of arrays or objects to pluck property or element from

  • Returns:Array

    List with the specified property or array element from each element in x

Passthrough for Ramda's pluck function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a new list by plucking the same named property (or array element) off all objects in the list supplied.

If an item does not have the specified property or array index, result will contain undefined for that element.

Will return [undefined] if second argument is something other than a list or undefined.

Will throw an exception if undefined is passed in for second argument.

'use strict'
const pluck = require('@eluvio/elv-js-helpers/Functional/pluck')

const arrOfObj = [{a: 1, b:2}, {b:2, c:3}]

pluck('b', arrOfObj)             //=> [2, 2]

pluck('a', arrOfObj)             //=> [1, undefined]

const arrOfArr = [['a', 'b'], ['b', 'c', 'd']]

pluck(1, arrOfArr)               //=> ['b', 'c']

pluck(2, arrOfArr)               //=> [undefined, 'd']

pluck(3, 3)                      //=> [undefined]

pluck(3, undefined)              //=> EXCEPTION: 'Cannot read properties of undefined'

// function is curried: call with just first param to obtain a more specialized function
const getFirstElements = pluck(0)

getFirstElements(arrOfArr)       //=> ['a', 'b']

PositiveFracStrModelModel

const PositiveFracStrModel = require('@eluvio/elv-js-helpers/Model/PositiveFracStrModel')
* → * | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

  • A Javascript String
  • Is in the form 'x' or 'x/y' where x and y are positive integers

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const PositiveFracStrModel = require('@eluvio/elv-js-helpers/Model/PositiveFracStrModel')

PositiveFracStrModel('42')    //=> '42'

PositiveFracStrModel('0')     //=> EXCEPTION: 'Value must be > 0 (got: "0")'

PositiveFracStrModel('42/2')  //=> '42/2'

PositiveFracStrModel('foo')   //=> EXCEPTION: 'Value must be a string in the form of a whole number or a fraction (got: "foo")'

PositiveIntModelModel

const PositiveIntModel = require('@eluvio/elv-js-helpers/Model/PositiveIntModel')
* → * | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const PositiveIntModel = require('@eluvio/elv-js-helpers/Model/PositiveIntModel')

PositiveIntModel(42)    //=> 42

PositiveIntModel(0)     //=> EXCEPTION: 'Value must be > 0 (got: 0)'

PositiveIntModel(4.2)   //=> EXCEPTION: 'Value must be an integer (got: 4.2)'

PositiveIntModel('foo') //=> EXCEPTION: 'expecting Number, got String "foo"'

PositiveIntModel(Infinity) //=> EXCEPTION: 'Value must be an integer (got: Infinity)'

PositiveIntModel(-Infinity) //=> EXCEPTION: 'Value must be an integer (got: -Infinity)'

PositiveNumModelModel

const PositiveNumModel = require('@eluvio/elv-js-helpers/Model/PositiveNumModel')
* → * | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:Number

    The validated input

An ObjectModel which validates that an input is:

If input passes validations, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const PositiveNumModel = require('@eluvio/elv-js-helpers/Model/PositiveNumModel')

PositiveNumModel(42)        //=> 42

PositiveNumModel(0)         //=> EXCEPTION: 'Value must be > 0 (got: 0)'

PositiveNumModel('foo')     //=> EXCEPTION: 'expecting Number, got String "foo"'

PositiveNumModel(Infinity)  //=> Infinity

PositiveNumModel(-Infinity) //=> EXCEPTION: 'Value must be > 0 (got: -Infinity)'

redactConversion

const redact = require('@eluvio/elv-js-helpers/Conversion/redact')
(a, [b], c) → a
Parameters
  • Anyvalue

    The value to redact

  • Array.<RegExp>addlPatterns

    Any additional patters to test keys against

  • stringparentKey

    the key that value was stored under, if any

  • Returns:*

Redacts string values within objects. Used to filter data before logging.

If passed an object or array, will recursively traverse it and construct a copy where object string values stored under certain keys are replaced with redacted versions.

If an object key is associated with a value that is a string, the key is tested against an array of regular expressions (REDACT_PATTERNS, plus any additional patterns passed in). If any match, then the string will be replaced with a redacted version:

  • Strings longer than 10 characters are replaced by '[REDACTED ...' + last 4 chars + ']'
  • Strings 10 characters long or less are replaced by '[REDACTED]'

If passed anything other than an object or array, will return the original value.

'use strict'
const redact = require('@eluvio/elv-js-helpers/Conversion/redact')

const data = {
  user: 'foo',
  password: 'my very long password',
  key: '1234'
}

const redacted = JSON.stringify(redact(data))

console.log(redacted)    //=> OUTPUT: '{"user":"foo","password":"[REDACTED ...word]","key":"[REDACTED]"}'

const arr = [
  {password: 'x'},
  {PRIVATE_KEY: '1234'},
  {foo: 'bar'}
]

const redactedArr = JSON.stringify(redact(arr))
console.log(redactedArr)    //=> OUTPUT: '[{"password":"[REDACTED]"},{"PRIVATE_KEY":"[REDACTED]"},{"foo":"bar"}]'

REDACT_PATTERNSConstant

const REDACT_PATTERNS = require('@eluvio/elv-js-helpers/Constant/REDACT_PATTERNS')

Type:Array.<RegExp>"[{},{},{},{},{},{},{},{},{},{},{}]"

Array of Regular Expressions used by redact() to decide whether a particular object attribute should have its value redacted.

'use strict'
const REDACT_PATTERNS = require('@eluvio/elv-js-helpers/Conversion/REDACT_PATTERNS')

const shouldRedact = x => REDACT_PATTERNS.find(pattern => pattern.test(x)) !== undefined;

shouldRedact('Password')     //=> true

shouldRedact('My_secret')     //=> true

shouldRedact('foo')          //=> false

reduceFunctional

const reduce = require('@eluvio/elv-js-helpers/Functional/reduce')
((a, b) → a) → a → [b] → a
λcurried function
Parameters
  • function(unnamed)

    the iterator function, accepting an accumulator (a) and the current list element (b) and returning an updated value for accumulator

  • Any(unnamed)

    initial value for accumulator

  • Returns:*

    final value of accumulator

Passthrough for Ramda's reduce function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a value created by iterating through a list with an accumulator and a function, successively calling the function with the updated accumulator and next element as the arguments.

'use strict'
const reduce = require('@eluvio/elv-js-helpers/Functional/reduce')

const arrOfInt = [1, 2, 3, 4, 5]

const add = (a,b) => a+b
const mult = (a,b) => a*b

reduce(add, 0, arrOfInt)      //=> 15

reduce(mult, 1, arrOfInt)     //=> 120

// note that choosing proper initial value for accumulator is important!
reduce(mult, 0, arrOfInt)     //=> 0

const append = (a,b) => a.concat([b])

reduce(append, [], arrOfInt)  //=> [1, 2, 3, 4, 5]

reFromTemplateConversion

const reFromTemplate = require('@eluvio/elv-js-helpers/Conversion/reFromTemplate')
[string], …stringsAndOrRegExps → RegExp | EXCEPTION
Parameters
  • Returns:RegExp

Javascript tagged template function to allow composing regular expressions.

Throws an exception if all sub-regexes do not have the same flags.

'use strict'
const reFromTemplate = require('@eluvio/elv-js-helpers/Conversion/reFromTemplate')

const RE_LETTER = /[a-zA-Z]/
const RE_DIGIT = /[0-9]/

const RE_UNICODE_LETTER = /\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/u
const RE_UNICODE_DIGIT = /\p{Nd}/u

const RE_LETTER_DIGIT = reFromTemplate`${RE_LETTER}${RE_DIGIT}`

const RE_UNICODE_LETTER_DIGIT = reFromTemplate`${RE_UNICODE_LETTER}${RE_UNICODE_DIGIT}`

RE_LETTER_DIGIT.source                           //=> '(?:[a-zA-Z])(?:[0-9])'
RE_LETTER_DIGIT.flags                            //=> ''

RE_UNICODE_LETTER_DIGIT.source                   //=> '(?:\\p{Lu}|\\p{Ll}|\\p{Lt}|\\p{Lm}|\\p{Lo})(?:\\p{Nd})'
RE_UNICODE_LETTER_DIGIT.flags                    //=> 'u'

reFromTemplate`${RE_DIGIT}${RE_UNICODE_LETTER}`  //=> EXCEPTION: 'All interpolated regular expressions must have the same flags (found: ["","u"])'

RE_LETTER_DIGIT.test('a4')                       //=> true
RE_LETTER_DIGIT.test('4a')                       //=> false
RE_LETTER_DIGIT.test('Å𝟜')                      //=> false
RE_LETTER_DIGIT.test('𝟜Å')                      //=> false

RE_UNICODE_LETTER_DIGIT.test('a4')               //=> true
RE_UNICODE_LETTER_DIGIT.test('4a')               //=> false
RE_UNICODE_LETTER_DIGIT.test('Å𝟜')               //=> true
RE_UNICODE_LETTER_DIGIT.test('𝟜Å')               //=> false

// strings are interpolated as literal match
const FOO_STR = 'foo'
const BAR_STR = 'bar'

const RE_FOOBAR = reFromTemplate`^${FOO_STR}${BAR_STR}$`

RE_FOOBAR.test('foobar')                              //=> true
RE_FOOBAR.test('foobarbar')                           //=> false
RE_FOOBAR.test('FOOBAR')                              //=> false

// if sub-regexps have start/end matchers, it can result in regexps that never match
const RE_FOO_ONLY = /^foo$/
const RE_BAR_ONLY = /^bar$/
const RE_FOOBAR_ONLY = reFromTemplate`^${RE_FOO_ONLY}${RE_BAR_ONLY}$`

RE_FOOBAR_ONLY.test('foobar')                        //=> false
RE_FOOBAR_ONLY.test('foobarbar')                     //=> false
RE_FOOBAR_ONLY.test('FOOBAR')                        //=> false

resultToPOJOConversion

const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')
Result [e] a → Object
Parameters
  • Resultresult

    The Crocks Result instance to convert

  • Returns:Object

Converts a Crocks Result to a Plain Old Javascript Object.

If the Result is an Ok, returns {ok: true, value: a}, where a is the value wrapped by the Ok

If the Result is an Err, returns {ok: false, errMsgs: uniqErrStringArray, errors: arrayErrVal} where errors is the array value wrapped by the Err (often an array of Javascript Error objects), and errMsgs is the result of passing each item in that array to String() then removing duplicates.

Throws an error if the Result is an Err that does not contain an array. (This situation is not usually encountered, as the Err() function performs automatic conversion to single-element array if the input is not an array)

'use strict'
const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const dumpJSON = require('@eluvio/elv-js-helpers/Misc/dumpJSON')

resultToPOJO(Ok(42))                 //=> {ok: true, value: 42}

resultToPOJO(Err(['query invalid'])) //=> {ok: false, errMsgs: ["query invalid"], errors: ["query invalid"]}

const e = RangeError('value too large')
dumpJSON(resultToPOJO(Err([e])))     //=> OUTPUT: `{
                                     //              "ok": false,
                                     //              "errMsgs": [
                                     //                "RangeError: value too large"
                                     //              ],
                                     //              "errors": [
                                     //                {}
                                     //              ]
                                     //            }`

resultUnwrapConversion

const resultUnwrap = require('@eluvio/elv-js-helpers/Conversion/resultUnwrap')
Result e a → e | a
Parameters
  • Anyx

    The Crocks Result instance to unwrap

  • Returns:Any

Returns the value wrapped by a Crocks Result, whether it is an Ok or an Err

Throws an exception if not passed a Result.

See also resultToPOJO

'use strict'
const resultUnwrap = require('@eluvio/elv-js-helpers/Conversion/resultUnwrap')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

resultUnwrap(Err(['invalid query'])) //=> ['invalid query']

resultUnwrap(Ok(42))                 //=> 42

reverseFunctional

const reverse = require('@eluvio/elv-js-helpers/Functional/reverse')
a :: String | Array => a → a
Parameters
  • Stringx

    the item to reverse

  • Returns:String

    Reversed string or array

Passthrough for Ramda's reverse function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a new list or string with the elements or characters in reverse order.

'use strict'
const reverse = require('@eluvio/elv-js-helpers/Functional/reverse')

reverse([1, 2, 3])                 //=> [3, 2, 1]

reverse("abc")                 //=> "cba"

RE_BASE58_CHARConstant

const RE_BASE58_CHAR = require('@eluvio/elv-js-helpers/Constant/RE_BASE58_CHAR')

Type:RegExp{}

RegExp used for validation of a Base58 character.

NOTE: This RegExp will match a string that contains a Base58 character anywhere within. It is intended for use in more complex RegExps created with reFromTemplate()

'use strict'
const RE_BASE58_CHAR = require('@eluvio/elv-js-helpers/Validation/RE_BASE58_CHAR')

RE_BASE58_CHAR.test('1')          //=> true

RE_BASE58_CHAR.test('l')          //=> false

RE_BASE58_CHAR.test('l1l')        //=> true

const reFromTemplate = require('@eluvio/elv-js-helpers/Conversion/reFromTemplate')

const RE_SINGLE_BASE58_CHAR = reFromTemplate`^${RE_BASE58_CHAR}$`

RE_SINGLE_BASE58_CHAR.test('1')   //=> true

RE_SINGLE_BASE58_CHAR.test('l')   //=> false

RE_SINGLE_BASE58_CHAR.test('l1l') //=> false

RE_RATIONALConstant

const RE_RATIONAL = require('@eluvio/elv-js-helpers/Constant/RE_RATIONAL')

Type:RegExp{}

RegExp used for validation of rational numbers expressed as strings of form x, -x, x/y, or -x/y, where x and y are integers and y !== 0.

Leading zeroes are allowed.

Capture groups parse the string into separate matches for numerator and slash+denominator.

'use strict'
const RE_RATIONAL = require('@eluvio/elv-js-helpers/Validation/RE_RATIONAL')

RE_RATIONAL.test('0')                              //=> true

RE_RATIONAL.test('-0')                             //=> true

RE_RATIONAL.test('0/1')                            //=> true

RE_RATIONAL.test('0/010')                          //=> true

RE_RATIONAL.test('1/0')                            //=> false

RE_RATIONAL.test('-0')                             //=> true

RE_RATIONAL.test('3.14')                           //=> false

RE_RATIONAL.test('9 1/2')                          //=> false

RE_RATIONAL.test('19/2')                           //=> true

RE_RATIONAL.test('007')                            //=> true

const fracString = '22/7'
const match = fracString.match(RE_RATIONAL)
if (!match) throw Error('Rational number string not in proper format')

// first capture group is numerator:
match[1]                                           //=> '22'
// second capture group is slash + denominator:
match[2]                                           //=> '/7'

RE_UTC_TIMESTAMPConstant

const RE_UTC_TIMESTAMP = require('@eluvio/elv-js-helpers/Constant/RE_UTC_TIMESTAMP')

Type:RegExp{}

RegExp used for first-pass validation of UTC timestamp of form YYYY-MM-DDThh:mm:ssZ, e.g. '2022-01-01T14:00:00Z'.

Capture groups parse the string into separate matches for year/month/day/hour/minute/second.

'use strict'
const RE_UTC_TIMESTAMP = require('@eluvio/elv-js-helpers/Datetime/RE_UTC_TIMESTAMP')

RE_UTC_TIMESTAMP.test('2022-01-02T03:45:00Z')     //=> true

RE_UTC_TIMESTAMP.test('foo')                      //=> false

const utcString = '2022-01-02T03:45:00Z'

const match = utcString.match(RE_UTC_TIMESTAMP)
if (!match) throw Error('UTC timestamp not in proper format')

// year
parseInt(match[1], 10)                            //=> 2022
// month
parseInt(match[2], 10)                            //=> 1
// day
parseInt(match[3], 10)                            //=> 2
// hour
parseInt(match[4], 10)                            //=> 3
// minute
parseInt(match[5], 10)                            //=> 45
// second
parseInt(match[6], 10)                            //=> 0

const utcStringFrac = '2022-01-02T03:45:00.123Z'
const fracMatch = utcStringFrac.match(RE_UTC_TIMESTAMP)

// fractional seconds
parseFloat(fracMatch[7])                              //=> 0.123

RE_UUIDConstant

const RE_UUID = require('@eluvio/elv-js-helpers/Constant/RE_UUID')

Type:RegExp{}

RegExp used for validation of UUID strings in format '00000000-0000-0000-0000-000000000000'

Both upper case and lower case are accepted for hex digits.

'use strict'
const RE_UUID = require('@eluvio/elv-js-helpers/Validation/RE_UUID')

RE_UUID.test('0')                                      //=> false

RE_UUID.test('ABCDEF00-0000-0000-0000-000000000000')   //=> true

RE_UUID.test('abcdef00-0000-0000-0000-000000000000')   //=> true

RE_UUID.test('abcdef00-0000-0000-0000-ABCDEF000000')   //=> true

RE_UUID_LOWER_CASEConstant

const RE_UUID_LOWER_CASE = require('@eluvio/elv-js-helpers/Constant/RE_UUID_LOWER_CASE')

Type:RegExp{}

RegExp used for validation of UUID strings in format '00000000-0000-0000-0000-000000000000' using only lower case letters for hex digits

(Note that this is non-standard, RFC4122 specifies that both upper and lower case letters are acceptable)

'use strict'
const RE_UUID_LOWER_CASE = require('@eluvio/elv-js-helpers/Validation/RE_UUID_LOWER_CASE')

RE_UUID_LOWER_CASE.test('0')                                      //=> false

RE_UUID_LOWER_CASE.test('ABCDEF00-0000-0000-0000-000000000000')   //=> false

RE_UUID_LOWER_CASE.test('abcdef00-0000-0000-0000-000000000000')   //=> true

RE_UUID_LOWER_CASE.test('abcdef00-0000-0000-0000-ABCDEF000000')   //=> false

RE_UUID_UPPER_CASEConstant

const RE_UUID_UPPER_CASE = require('@eluvio/elv-js-helpers/Constant/RE_UUID_UPPER_CASE')

Type:RegExp{}

RegExp used for validation of UUID strings in format '00000000-0000-0000-0000-000000000000' using only upper case letters for hex digits

(Note that this is non-standard, RFC4122 specifies that both upper and lower case letters are acceptable)

'use strict'
const RE_UUID_UPPER_CASE = require('@eluvio/elv-js-helpers/Validation/RE_UUID_UPPER_CASE')

RE_UUID_UPPER_CASE.test('0')                                      //=> false

RE_UUID_UPPER_CASE.test('ABCDEF00-0000-0000-0000-000000000000')   //=> true

RE_UUID_UPPER_CASE.test('abcdef00-0000-0000-0000-000000000000')   //=> false

RE_UUID_UPPER_CASE.test('abcdef00-0000-0000-0000-ABCDEF000000')   //=> false

satisfiesBetweenBoundsBoolean

const satisfiesBetweenBounds = require('@eluvio/elv-js-helpers/Boolean/satisfiesBetweenBounds')
a → Boolean → ((a, a) → Integer) → a → Boolean
λcurried function
Parameters
  • AnylowerBound

    the lower bound to be satisfied

  • AnyupperBound

    the upper bound to be satisfied

  • BooleanlowerInclusive

    if true, then value is allowed equal lowerBound

  • BooleanupperInclusive

    if true, then value is allowed equal upperBound

  • functioncomparatorFn

    The function to be used to compare value with lowerBound and upperBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise.

  • Anyvalue

    The item to check against lowerBound and upperBound

  • Returns:Boolean

Returns true if value satisfies specified bounds, false otherwise

Note that this function performs no type checking and relies on comparatorFn to determine if input satisfies bounds.

If called with fewer than 6 arguments, will return a partially applied function

'use strict'
const satisfiesBetweenBounds = require('@eluvio/elv-js-helpers/Boolean/satisfiesBetweenBounds')

const compare = require('@eluvio/elv-js-helpers/Functional/compare')

satisfiesBetweenBounds(0, 42, true, true, compare, 42)    //=> true

satisfiesBetweenBounds(0, 42, true, true, compare, 0)     //=> true

satisfiesBetweenBounds(0, 42, true, true, compare, -1)    //=> false

satisfiesBetweenBounds(0, 42, false, false, compare, 0)   //=> false

// function is curried: call with fewer params to obtain a narrower function
const isFromZeroToOne = satisfiesBetweenBounds(0, 1, true, true, compare)

isFromZeroToOne(0.5) //=> true

isFromZeroToOne(1)   //=> true

isFromZeroToOne(1.5) //=> false

satisfiesLowerBoundBoolean

const satisfiesLowerBound = require('@eluvio/elv-js-helpers/Boolean/satisfiesLowerBound')
a → Boolean → ((a, a) → Integer) → a → Boolean
λcurried function
Parameters
  • AnylowerBound

    the lower bound to be satisfied

  • Booleaninclusive

    if true, then value is allowed equal lowerBound

  • functioncomparatorFn

    The function to be used to compare value and lowerBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise.

  • Anyvalue

    The item to check against lowerBound

  • Returns:Boolean

Returns true if value satisfies specified bound, false otherwise

Note that this function performs no type checking and relies on comparatorFn to determine if input satisfies bound.

If called with fewer than 4 arguments, will return a partially applied function

'use strict'
const satisfiesLowerBound = require('@eluvio/elv-js-helpers/Boolean/satisfiesLowerBound')

const compare = require('@eluvio/elv-js-helpers/Functional/compare')

satisfiesLowerBound(0, true, compare, 42)   //=> true

satisfiesLowerBound(0, true, compare, 0)    //=> true

satisfiesLowerBound(0, true, compare, -1)   //=> false

satisfiesLowerBound(0, false, compare, 0)   //=> false

// function is curried: call with fewer params to obtain a narrower function
const isPositive = satisfiesLowerBound(0, false, compare)

isPositive(-1)  //=> false

isPositive(0)   //=> false

isPositive(1)   //=> true

satisfiesUpperBoundBoolean

const satisfiesUpperBound = require('@eluvio/elv-js-helpers/Boolean/satisfiesUpperBound')
a → Boolean → ((a, a) → Integer) → a → Boolean
λcurried function
Parameters
  • AnyupperBound

    the upper bound to be satisfied

  • Booleaninclusive

    if true, then value is allowed equal upperBound

  • functioncomparatorFn

    The function to be used to compare value and upperBound. Must accept two values and return -1 if first value is less than the second, 1 if the second value is less than the first, and zero otherwise.

  • Anyvalue

    The item to check against upperBound

  • Returns:Boolean

Returns true if value satisfies specified bound, false otherwise

Note that this function performs no type checking and relies on comparatorFn to determine if input satisfies bound.

If called with fewer than 4 arguments, will return a partially applied function

'use strict'
const satisfiesUpperBound = require('@eluvio/elv-js-helpers/Boolean/satisfiesUpperBound')

const compare = require('@eluvio/elv-js-helpers/Functional/compare')

satisfiesUpperBound(42, true, compare, 42)   //=> true

satisfiesUpperBound(42, true, compare, 0)    //=> true

satisfiesUpperBound(42, true, compare, -1)   //=> true

satisfiesUpperBound(42, false, compare, 42)  //=> false

// function is curried: call with fewer params to obtain a narrower function
const isNegative = satisfiesUpperBound(0, false, compare)

isNegative(-1)  //=> true

isNegative(0)   //=> false

isNegative(1)   //=> false

setArityFunctional

const setArity = require('@eluvio/elv-js-helpers/Functional/setArity')
Number → ((*) → a) → (*) → a
λcurried function
Parameters
  • number(unnamed)

    arity - Number of arguments for the returned function to accept

  • function(unnamed)

    The function to convert

  • Returns:function

    Curried version of function with fixed argument count

Renamed passthrough for the nAry() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Converts a function that takes a variable number of arguments and converts to a curried function that one that specified number of arguments.

'use strict'
const setArity = require('@eluvio/elv-js-helpers/Functional/setArity')

const maxOfThree = setArity(3, Math.max)

// creates partially applied function with 1 argument applied (waiting for 2 more):
const maxNeedTwoMore = maxOfThree(42)

// creates partially applied function with 2 arguments applied (waiting for 1 more):
const maxNeedOneMore = maxNeedTwoMore(0)

maxNeedOneMore(-42)                  //=> 42

setPathFunctional

const setPath = require('@eluvio/elv-js-helpers/Functional/setPath')
Idx = String | Int | Symbol => [Idx] → * → Object → Object
λcurried function
Parameters
  • ArraypathArray

    the path to set, expressed as an array

  • Anyvalue

    the value to store at path

  • Objectobject

    the original object

  • Returns:Object

    Shallow copy of object with

Renamed passthrough for Ramda's assocPath function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a shallow clone of object with value set at specified path. Any missing or non-object keys in path will be overridden. WARNING: arrays along the path will be converted into objects with numeric strings as keys (see examples)

Unlike getPath, does not support negative numbers as indexes to set element counting from end of array. Ramda will actually end up adding a property to the array using string of negative number as the key. This function will throw an error instead.

For safety, you should clone the original object before passing into setPath.

'use strict'
const setPath = require('@eluvio/elv-js-helpers/Functional/setPath')

const clone = require('@eluvio/elv-js-helpers/Functional/clone')
const myObject = {foo: {bar: [1, 2, 3]}}

setPath(['foo'], 42, clone(myObject))                   //=> {foo: 42}

setPath(['bar'], 42, clone(myObject))                   //=> {bar: 42, foo: {bar: [1, 2, 3]}}

// numeric values interpreted as array indexes
setPath(['foo', 'bar', 0], 42, clone(myObject))         //=> {foo: {bar: [42, 2, 3]}}

// empty values inserted into existing arrays if needed
setPath(['foo', 'bar', 5], 42, clone(myObject))         //=> {foo: {bar: [1, 2, 3, , , 42]}}

// WARNING: using a string expressing a number when an array exists at path causes other array elements to be
// converted to key:value pairs
setPath(['foo', 'bar', '0'], 42, clone(myObject))       //=> {foo: {bar: {0: 42, 1: 2, 2: 3}}}

setPath(['foo', 'bar', 'baz'], 42, clone(myObject))     //=> {foo: {bar: {0: 1, 1: 2, 2: 3, baz: 42}}}

// empty values inserted into new arrays if needed
setPath(['foo', 'bar', 'baz', 5], 42, clone(myObject))  //=> {foo: {bar: {0: 1, 1: 2, 2: 3, baz: [ , , , , , 42]}}}

// negative numbers NOT supported as array indexes
setPath(['foo', 'bar', -1], 42, clone(myObject))        //=> EXCEPTION: "expecting Array[2] to be String or NonNegativeInteger, got Number -1"

sortByFunctional

const sortBy = require('@eluvio/elv-js-helpers/Functional/sortBy')
Ord b => (a → b) → [a] → [a]
λcurried function
Parameters
  • function(unnamed)

    the function to obtain the sort key for each element

  • Array(unnamed)

    the list to sort

  • Returns:Array

Passthrough for Ramda's sortBy function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Sorts a list according the result of calling a function on each element of the list.

'use strict'
const sortBy = require('@eluvio/elv-js-helpers/Functional/sortBy')

const sortByName = sortBy(x => x.name)
const sortByNameCaseInsensitive = sortBy(x => x.name.toLowerCase())

sortByName([
  {name: "alpha"},
  {name: "Bravo"},
  {name: "charlie"}
]).map(x => x.name)                //=> ['Bravo', 'alpha', 'charlie']

sortByNameCaseInsensitive([
  {name: "alpha"},
  {name: "Bravo"},
  {name: "charlie"}
]).map(x => x.name)                //=> ['alpha', 'Bravo', 'charlie']

StringModelModel

const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is a Javascript String

If input passes validation, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const StringModel = require('@eluvio/elv-js-helpers/Model/StringModel')

StringModel('foo') //=> 'foo'

StringModel(42)    //=> EXCEPTION: 'expecting String, got Number 42'

sysLocaleDatetime

const sysLocale = require('@eluvio/elv-js-helpers/Datetime/sysLocale')
() → String
Parameters
  • Returns:String

Returns locale string from current environment (see http://www.lingoes.net/en/translator/langcode.htm)

The locale string is used to format dates and times

'use strict'
const sysLocale = require('@eluvio/elv-js-helpers/Datetime/sysLocale')

sysLocale() //=> 'en-US'

sysTimezoneDatetime

const sysTimezone = require('@eluvio/elv-js-helpers/Datetime/sysTimezone')
() → String
Parameters
  • Returns:String

Returns Datetime zone string from current environment

'use strict'
const sysTimezone = require('@eluvio/elv-js-helpers/Datetime/sysTimezone')

sysTimezone() //=> 'America/Los_Angeles'

TFunctional

const T = require('@eluvio/elv-js-helpers/Functional/T')
{} → a
Parameters
  • Returns:Boolean

    true

Ignores input and always returns true.

Used for composing functional workflows, often indicating 'always'.

'use strict'
const T = require('@eluvio/elv-js-helpers/Functional/T')

T(42)   //=> true

T()     //=> true

tailFunctional

const tail = require('@eluvio/elv-js-helpers/Functional/tail')
[*] → [*] | EXCEPTION
String → String
Parameters
  • List(unnamed)

    an iterable list of elements

  • Returns:Array

    Array containing all but the first element, or String containing all but the first character

Passthrough for Ramda's tail function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns all but the first element of a list or string

See also head, init, last

'use strict'
const tail = require('@eluvio/elv-js-helpers/Functional/tail')

tail([1, 2, 3, 4, 5])      //=> [2, 3, 4, 5]
tail([1])                  //=> []
tail([])                   //=> []

tail('abc')                //=> 'bc'
tail('a')                  //=> ''
tail('')                   //=> ''

// NOTE: bad data types are ignored
tail(0)                    //=> []

tail({foo: 'bar'})         //=> []

// undefined will produce an exception
tail(undefined)            //=> EXCEPTION: 'Cannot read properties of undefined'

throwErrorMisc

const throwError = require('@eluvio/elv-js-helpers/Misc/throwError')
String → THROW
Parameters
  • Stringmessage

    Error message for exception

  • Returns:Nothing

Throws an exception. Used to allow terser code, e.g. replacing if/else with a ternary expression.

'use strict'
const throwError = require('@eluvio/elv-js-helpers/Misc/throwError')

throwError('clear and helpful error message') //=> EXCEPTION: 'clear and helpful error message'

throwIfArgsBadValidation

const throwIfArgsBad = require('@eluvio/elv-js-helpers/Validation/throwIfArgsBad')
ObjectOrModel → * → undefined | THROW
λcurried function
Parameters
  • ObjectmodelOrObj

    a Model or an Object that can be used as an ObjectModel spec

  • Anyargs

    the input to validate

  • Returns:Any

Throws an exception with the calling function's name if args object does not validate successfully.

Meant to be used at the beginning of a function.

Usually the function accepts named parameters (i.e. an object) and the validation will be checking an object.

WARNING: must be called directly by the function in order to show calling function name correctly - do not pipe/compose.

'use strict'
const throwIfArgsBad = require('@eluvio/elv-js-helpers/Validation/throwIfArgsBad')

const defObjectModel = require('@eluvio/elv-js-helpers/ModelFactory/defObjectModel')
const NonNegativeIntModel = require('@eluvio/elv-js-helpers/Model/NonNegativeIntModel')

const PersonModel = defObjectModel('Person', {first: String, last: String, age: NonNegativeIntModel})

const getAge = person => {
  throwIfArgsBad(PersonModel, person)
  return person.age
}

const validPerson = {first: 'Arthur', last: 'Dent', age: 30}
getAge(validPerson)                                          //=> 30

const badData = {first: 'Arthur', last: 'Dent'}
getAge(badData)                                              //=> EXCEPTION: 'getAge() expecting age to be Number, got undefined'

getAge(42)                                                   //=> EXCEPTION: 'getAge() expecting Object, got Number 42'

throwIfFalseValidation

const throwIfFalse = require('@eluvio/elv-js-helpers/Validation/throwIfFalse')
String → a → a | THROW
λcurried function
Parameters
  • Stringmessage

    the error message to use in the exception

  • Anyvalue

    the value to check for falsiness

  • Returns:Any

Throws an exception with the specified message if a falsy value is passed in. Otherwise returns the truthy value unchanged.

'use strict'
const throwIfFalse = require('@eluvio/elv-js-helpers/Validation/throwIfFalse')

const PASSWORD_REGEX_4 = /[A-Z]{4}/
const PASSWORD_REGEX_42 = /[A-Z]{42}/
const password = 'ABCD'

throwIfFalse('password must be 42 upper-case letters', PASSWORD_REGEX_42.test(password)) //=> EXCEPTION: 'password must be 42 upper-case letters'

throwIfFalse('password must be 4 upper-case letters', PASSWORD_REGEX_4.test(password))   //=> true

throwIfFalse('foo', 42)                                                                  //=> 42

throwIfFalse('foo', [])                                                                  //=> []

throwIfTrueValidation

const throwIfTrue = require('@eluvio/elv-js-helpers/Validation/throwIfTrue')
String → a → a | THROW
λcurried function
Parameters
  • Stringmessage

    the error message to use in the exception

  • Anyvalue

    the value to check for truthiness

  • Returns:Any

Throws an exception with the specified message if a truthy value is passed in. Otherwise returns the falsy value unchanged.

'use strict'
const throwIfTrue = require('@eluvio/elv-js-helpers/Validation/throwIfTrue')

const x = 0
const y = 42

throwIfTrue('division by zero', x === 0) //=> EXCEPTION: "division by zero"

throwIfTrue('division by zero', y === 0) //=> false

throwIfTrue('foo', null)                 //=> null

throwIfTrue('foo', 0)                    //=> 0

throwIfUndefinedValidation

const throwIfUndefined = require('@eluvio/elv-js-helpers/Validation/throwIfUndefined')
String → a → a | THROW
λcurried function
Parameters
  • Stringmessage

    the error message to use in the exception

  • Anyvalue

    the value to check if undefined

  • Returns:Any

Throws an exception with the specified message if undefined is passed in. Otherwise returns the value unchanged.

'use strict'
const throwIfUndefined = require('@eluvio/elv-js-helpers/Validation/throwIfUndefined')

let u
const x = 0
let y = 42

throwIfUndefined('value is undefined', u)   //=> EXCEPTION: "value is undefined"

throwIfUndefined('value is undefined', x)   //=> 0

throwIfUndefined('value is undefined', y)   //=> 42

throwIfUndefined('value is undefined')()    //=> EXCEPTION: "value is undefined"

throwsExceptionBoolean

const throwsException = require('@eluvio/elv-js-helpers/Boolean/throwsException')
a → Boolean
Parameters
  • functionfn

    The function to test

  • Returns:Boolean

Returns true if fn() throws an exception when called. Returns false otherwise.

'use strict'
const throwsException = require('@eluvio/elv-js-helpers/Boolean/throwsException')

throwsException(() => Object().foo.bar)  //=> true

throwsException(() => 42/42)             //=> false

// returns `true` if passed something that cannot be called.
throwsException(0)                       //=> true

timesFunctional

const times = require('@eluvio/elv-js-helpers/Functional/times')
(Number → a) → Number → [a]
λcurried function
Parameters
  • functionfn

    the function to call with index

  • integerrepeatCount

    the number of times to call the function

  • Returns:Array

    List with result of function call(s)

Passthrough for Ramda's times function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a list containing result of passing 0 based index to a function the specified number of times, incrementing index each time.

'use strict'
const times = require('@eluvio/elv-js-helpers/Functional/times')

const double = x => x * 2

times(double, 3)                 //=> [0, 2, 4]

// function is curried: call with just first param to obtain a more specialized function
const getSquares = times(x => x ** 2)

getSquares(4)                    //=> [0, 1, 4, 9]

toLocaleStringDatetime

const toLocaleString = require('@eluvio/elv-js-helpers/Datetime/toLocaleString')
(String | [String], Object) → (Date → String)
λcurried function
Parameters
  • Stringlocales

    The locales argument to pass to Date.toLocaleString()

  • Objectoptions

    The options argument to pass to Date.toLocaleString()

  • Returns:function

Takes two inputs (for locales and options and returns a function that will accept a Javascript Date object and return a string obtained by invoking its toLocaleString() method with the specified locales and options arguments.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString for more details.

See https://devhints.io/wip/intl-datetime for a list of options.

See https://gist.github.com/diogocapela/12c6617fc87607d11fd62d2a4f42b02a for a list of time zones.

'use strict'
const toLocaleString = require('@eluvio/elv-js-helpers/Datetime/toLocaleString')
const utcStrToDate = require('@eluvio/elv-js-helpers/Datetime/utcStrToDate')

const myDate = utcStrToDate('2022-03-01T14:00:00Z')

const USA_Pacific_short = toLocaleString(
  'en-US',
  {
    hour: 'numeric',
    day: 'numeric',
    minute: 'numeric',
    month: 'short',
    second: 'numeric',
    timeZone: 'America/Los_Angeles',
    timeZoneName: 'short'
  }
)

USA_Pacific_short(myDate)                //=> 'Mar 1, 6:00:00 AM PST'

const UK_long = toLocaleString(
  'en-GB',
  {
    dateStyle: 'full',
    timeStyle: 'long',
    timeZone: 'Europe/London'
  }
)

UK_long(myDate)                          //=> 'Tuesday, 1 March 2022 at 14:00:00 GMT'

// function is curried, it is possible to pass all arguments at once to define and invoke in one step:

const options = {
    dateStyle: 'short',
    timeStyle: 'short',
    timeZone: 'America/New_York'
}

toLocaleString('en-US', options, myDate) //=> '3/1/22, 9:00 AM'

toPairsConversion

const toPairs = require('@eluvio/elv-js-helpers/Conversion/toPairs')
Object → List (Pair String a)
Parameters
  • Object(unnamed)

    The object to convert

  • Returns:List

    List of Pairs

Passthrough for the toPairs() Crocks function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

See https://crocks.dev/docs/crocks/Pair.html#topairs for more details.

Converts an object into a Crocks List of Pair objects, each with key as first element and value as second element.

Not to be confused with Ramda's toPairs() function, which returns a 2-level regular Javascript array.

'use strict'
const toPairs = require('@eluvio/elv-js-helpers/Conversion/toPairs')

const kvPairs = toPairs({a:1, b:2})
kvPairs.inspect()                     //=> 'List [ Pair( "a", 1 ), Pair( "b", 2 ) ]'

truthTableFunctional

const truthTable = require('@eluvio/elv-js-helpers/Functional/truthTable')
[*] → [Boolean] → *
λcurried function
Parameters
  • ArraychoiceArray

    An array of items to choose from

  • Array.<Boolean>boolArray

    An array of booleans used to determine which element to return from choiceArray

  • Returns:Any

Returns an item from an array of choices, making the choice based on a separate array of booleans.

Used to express multilevel if-then control flows in a more Functional style.

// Given the following table:

// | isChild | isMale | result  |
// |---------|--------|---------|
// |    F    |    F   | 'woman' |
// |    F    |    T   |  'man'  |
// |    T    |    F   |  'girl' |
// |    T    |    T   |  'boy'  |

'use strict'
const truthTable = require('@eluvio/elv-js-helpers/Functional/truthTable')

let isChild = false
let isMale = false

truthTable(['woman','man','girl','boy'],[isChild, isMale]) //=> "woman"

// For comparison - expressed using if/then
if(isChild) {
  if(isMale) {
    return 'boy'
  } else {
    return 'girl'
  }
} else {
  if(isMale) {
    return 'man'
  } else {
    return 'woman'
  }
}

tryCatchFunctional

const tryCatch = require('@eluvio/elv-js-helpers/Functional/tryCatch')
((*) → b) → (*) → Result e b
λcurried function
Parameters
  • functionfn

    The function to convert

  • Returns:Result

Slightly modified version of the tryCatch() Crocks helper function (Copyright © 2016, Ian Hofmann-Hicks, ISC license)

Modified to use elv-js-helper's version of Err(), which wraps non-array values into a single-element array.

See https://crocks.dev/docs/functions/helpers.html#trycatch for more details.

Allows users of elv-js-helpers to use the function without adding the Crocks package as a dependency.

Converts the supplied function into one that returns an Ok if successful or an Err if it throws an error.

If the function is a method of a class instance you will need to suffix the function with .bind(your_instance_var) (see example below)

else the method call will execute with this set incorrectly, leading to confusing errors.

Note that calling tryCatch with just a function will not execute the function immediately - instead it will return another function that you can call with arguments.

To immediately invoke the function, use one of the following:

tryCatch(myFunction, arguments...)

tryCatch(myFunction)(arguments...)

If your function takes no arguments, you can use one of the following:

tryCatch(myFunction, undefined)

tryCatch(myFunction)()

'use strict'
const tryCatch = require('@eluvio/elv-js-helpers/Functional/tryCatch')

const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/resultToPOJO')

// Using tryCatch to create safe versions of functions that may throw exceptions:

const firstChar = x => x.charAt(0)
const safeFirstChar = tryCatch(firstChar)

const goodResult1 = safeFirstChar('42')
goodResult1.inspect()                     //=> 'Ok "4"'

const errResult1 = safeFirstChar(42)
resultToPOJO(errResult1).ok               //=> false
resultToPOJO(errResult1).errMsgs          //=> ['TypeError: x.charAt is not a function']

// Class instance methods require .bind():

const myRegex = /^[a-z]+$/
const safeTest = tryCatch(myRegex.test.bind(myRegex))

const goodResult2 = safeTest('abc')
goodResult2.inspect()                     //=> 'Ok true'
safeTest('42').inspect()                  //=> 'Ok false'

const badResult2 = safeTest(Symbol())
resultToPOJO(badResult2).ok               //=> false
resultToPOJO(badResult2).errMsgs          //=> ['TypeError: Cannot convert a Symbol value to a string']

// Forgetting to use .bind() with a class instance method will cause obscure errors:

const badTest = tryCatch(myRegex.test)
const badTestResult = badTest('abc')
resultToPOJO(badTestResult).ok               //=> false
resultToPOJO(badTestResult).errMsgs          //=> ['TypeError: Method RegExp.prototype.test called on incompatible receiver undefined']


// Using tryCatch like a Javascript try / catch block (immediately executing the function):

// argument(s) listed inside tryCatch:
const goodResult3 = tryCatch(firstChar, '42')
goodResult3.inspect()                     //=> 'Ok "4"'

// argument(s) listed after tryCatch:
const badResult3 = tryCatch(firstChar)(42)
resultToPOJO(badResult3).ok               //=> false
resultToPOJO(badResult3).errMsgs          //=> ['TypeError: x.charAt is not a function']

uniqFunctional

const uniq = require('@eluvio/elv-js-helpers/Functional/uniq')
[*] → [*]
Parameters
  • Array(unnamed)

    the array of elements

  • Returns:Array

    New list with only unique elements

Passthrough for Ramda's uniq function (Copyright © Scott Sauyet and Michael Hurley)

Allows users of elv-js-helpers to use the function without adding the Ramda package as a dependency.

Returns a new list containing only one copy of each equivalent element in the original list.

Internally uses Ramda's equals function to compare elements for equivalency (available in elv-js-helpers as isEquivalent)

'use strict'
const uniq = require('@eluvio/elv-js-helpers/Functional/uniq')

uniq([1, 2, 3, 2])                 //=> [1, 2, 3]

const obj1 = {foo: 'bar'}
const obj2 = {foo: 'bar'}
const obj3 = {bar: 'baz'}

uniq([obj1, obj2, obj3])           //=> [{foo: 'bar'}, {bar: 'baz'}]

// Strings are treated as arrays of characters
uniq('alphabet')                  //=> ['a', 'l', 'p', 'h', 'b', 'e', 't']

// Non-arrays are converted to empty array
uniq(99)                          //=> []

UTCStrModelModel

const UTCStrModel = require('@eluvio/elv-js-helpers/Model/UTCStrModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is:

  • A Javascript String
  • In UTC timestamp format e.g. '2022-01-01T14:00:00Z'
  • A valid Datetime

If input passes validation, will return the input

Throws an exception if passed in an invalid value.

'use strict'
const UTCStrModel = require('@eluvio/elv-js-helpers/Model/UTCStrModel')

UTCStrModel('2022-01-01T14:00:00Z') //=> '2022-01-01T14:00:00Z'

UTCStrModel('2022-01-01T14:00:00.123Z') //=> '2022-01-01T14:00:00.123Z'

UTCStrModel('2022-13-01T14:00:00Z') //=> EXCEPTION: 'Value is not a valid UTC datetime string (got: "2022-13-01T14:00:00Z")'

UTCStrModel('foo')                  //=> EXCEPTION: `Value is not in UTC format 'yyyy-mm-ddThh:mm:ss[.s...]Z' (got: "foo")`

UTCStrModel(42)                     //=> EXCEPTION: 'expecting String, got Number 42'

utcStrToDateDatetime

const utcStrToDate = require('@eluvio/elv-js-helpers/Datetime/utcStrToDate')
String → Date
Parameters
  • StringutcString

    The UTC timestamp to convert

  • Returns:Date

Converts a string in UTC format (e.g. '2022-01-01T14:00:00Z') to a Javascript Date

Throws an exception if input is not a valid UTC string

'use strict'
const utcStrToDate = require('@eluvio/elv-js-helpers/Datetime/utcStrToDate')

const dateObject = utcStrToDate('2022-01-01T14:00:00Z')
dateObject.valueOf()                                    //=> 1641045600000

utcStrToDate('2022-99-01T14:00:00Z')                    //=> EXCEPTION: 'Value is not a valid UTC datetime string (got: "2022-99-01T14:00:00Z")'

utcStrToDate(42)                                        //=> EXCEPTION: 'expecting String, got Number 42'

uuidFunctional

const uuid = require('@eluvio/elv-js-helpers/Functional/uuid')
() → a
Parameters
  • Returns:string

    The uuid

Passthrough for the v4() function from uuid _(Copyright © 2010-2020 Robert Kieffer and other contributors, MIT license) to generate a random UUID.

Allows users of elv-js-helpers to use the function without adding the uuid package as a dependency.

The UUID generated will have lower case letters for hex digits.

'use strict'
const uuid = require('@eluvio/elv-js-helpers/Misc/uuid')

const RE_UUID_LOWER_CASE = require('@eluvio/elv-js-helpers/Validation/RE_UUID_LOWER_CASE')

const u = uuid()
u.length                    //=> 36
RE_UUID_LOWER_CASE.test(u)  //=> true

UUIDStrLowerModelModel

const UUIDStrLowerModel = require('@eluvio/elv-js-helpers/Model/UUIDStrLowerModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is a Javascript String in UUID format e.g. '00000000-0000-0000-0000-000000000000' with only lower case letters for hex digits.

(Note that this is non-standard, RFC4122 specifies that both upper and lower case letters are acceptable)

Throws an exception if passed in an invalid value.

'use strict'
const UUIDStrLowerModel = require('@eluvio/elv-js-helpers/Model/UUIDStrLowerModel')

UUIDStrLowerModel('0')                                      //=> EXCEPTION: `Value is not in lower case UUID format '00000000-0000-0000-0000-000000000000' (got: "0")`

UUIDStrLowerModel('ABCDEF00-0000-0000-0000-000000000000')   //=> EXCEPTION: `Value is not in lower case UUID format '00000000-0000-0000-0000-000000000000' (got: "ABCDEF00-0000-0000-0000-000000000000")`

UUIDStrLowerModel('abcdef00-0000-0000-0000-000000000000')   //=> 'abcdef00-0000-0000-0000-000000000000'

UUIDStrLowerModel('abcdef00-0000-0000-0000-ABCDEF000000')   //=> EXCEPTION: `Value is not in lower case UUID format '00000000-0000-0000-0000-000000000000' (got: "abcdef00-0000-0000-0000-ABCDEF000000")`

UUIDStrModelModel

const UUIDStrModel = require('@eluvio/elv-js-helpers/Model/UUIDStrModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is a Javascript String in UUID format e.g. '00000000-0000-0000-0000-000000000000'

Both upper and lower case letters are accepted for hex digits

Throws an exception if passed in an invalid value.

'use strict'
const UUIDStrModel = require('@eluvio/elv-js-helpers/Model/UUIDStrModel')

UUIDStrModel('0')                                      //=> EXCEPTION: `Value is not in UUID format '00000000-0000-0000-0000-000000000000' (got: "0")`

UUIDStrModel('ABCDEF00-0000-0000-0000-000000000000')   //=> 'ABCDEF00-0000-0000-0000-000000000000'

UUIDStrModel('abcdef00-0000-0000-0000-000000000000')   //=> 'abcdef00-0000-0000-0000-000000000000'

UUIDStrModel('abcdef00-0000-0000-0000-ABCDEF000000')   //=> 'abcdef00-0000-0000-0000-ABCDEF000000'

UUIDStrUpperModelModel

const UUIDStrUpperModel = require('@eluvio/elv-js-helpers/Model/UUIDStrUpperModel')
* → String | THROW
Parameters
  • Any(unnamed)

    The input to validate

  • Returns:String

    The validated input

An ObjectModel which validates that an input is a Javascript String in UUID format e.g. '00000000-0000-0000-0000-000000000000' with only upper case letters for hex digits.

(Note that this is non-standard, RFC4122 specifies that both upper and lower case letters are acceptable)

Throws an exception if passed in an invalid value.

'use strict'
const UUIDStrUpperModel = require('@eluvio/elv-js-helpers/Model/UUIDStrUpperModel')

UUIDStrUpperModel('0')                                      //=> EXCEPTION: `Value is not in upper case UUID format '00000000-0000-0000-0000-000000000000' (got: "0")`

UUIDStrUpperModel('ABCDEF00-0000-0000-0000-000000000000')   //=> 'ABCDEF00-0000-0000-0000-000000000000'

UUIDStrUpperModel('abcdef00-0000-0000-0000-000000000000')   //=> EXCEPTION: `Value is not in upper case UUID format '00000000-0000-0000-0000-000000000000' (got: "abcdef00-0000-0000-0000-000000000000")`

UUIDStrUpperModel('abcdef00-0000-0000-0000-ABCDEF000000')   //=> EXCEPTION: `Value is not in upper case UUID format '00000000-0000-0000-0000-000000000000' (got: "abcdef00-0000-0000-0000-ABCDEF000000")`

validateWithModelValidation

const validateWithModel = require('@eluvio/elv-js-helpers/Validation/validateWithModel')
Model → (a → Result [String] a)
λcurried function
Parameters
  • ModelModel

    An ObjectModel definition to validate against

  • Anyinput

    The input to validate

  • Returns:function

Validates input against a Model and returns a Crocks Result instance. This returned instance will be an Ok wrapping the input data if it passed the Model's validations, or an Err wrapping an array of validation errors.

Function is curried, it can be called with just Model to return a validation function.

'use strict'
const validateWithModel = require('@eluvio/elv-js-helpers/Validation/validateWithModel')

const PositiveNumModel = require('@eluvio/elv-js-helpers/Model/PositiveNumModel')
const resultToPOJO = require('@eluvio/elv-js-helpers/Conversion/ResultToPOJO')

const goodResult = validateWithModel(PositiveNumModel, 42)
goodResult.inspect()                             //=> 'Ok 42'
resultToPOJO(goodResult).ok                      //=> true
resultToPOJO(goodResult).value                   //=> 42

const errZeroInput = validateWithModel(PositiveNumModel, 0)
resultToPOJO(errZeroInput).ok                    //=> false
resultToPOJO(errZeroInput).errMsgs               //=> ['PositiveNumber: Value must be > 0 (got: 0)']

const errStringInput = validateWithModel(PositiveNumModel, 'foo')
resultToPOJO(errStringInput).ok                  //=> false
resultToPOJO(errStringInput).errMsgs             //=> ['PositiveNumber: expecting Number, got String "foo"']

// function is curried, call with just 1 argument to return a more specific validation function
const validatePositiveNumber = validateWithModel(PositiveNumModel)

validatePositiveNumber(42).inspect()             //=> 'Ok 42'

resultToPOJO(validatePositiveNumber(0)).ok       //=> false

resultToPOJO(validatePositiveNumber('foo')).ok   //=> false

wrapNonArrayConversion

const wrapNonArray = require('@eluvio/elv-js-helpers/Conversion/wrapNonArray')
Non-array n => n | [a] → [n] | [a]
Parameters
  • Anyx

    The value to wrap in an array (if it is not already an array)

  • Returns:array

If value is not an array, returns an array containing the value, otherwise returns the original value

'use strict'
const wrapNonArray = require('@eluvio/elv-js-helpers/Conversion/wrapNonArray')

wrapNonArray(42)      //=> [42]

wrapNonArray([42])    //=> [42]

wrapNonArray([0, 42]) //=> [0, 42]

_boundBetweenErrMsgMisc

const _boundBetweenErrMsg = require('@eluvio/elv-js-helpers/Misc/_boundBetweenErrMsg')
a → a → Boolean → Boolean → String
Parameters
  • AnylowerBound
  • AnyupperBound
  • BooleanlowerInclusive

    Whether values are allowed to equal lowerBound

  • BooleanupperInclusive

    Whether values are allowed to equal upperBound

  • Returns:String

Returns an error message for a failed upper bound condition

'use strict'
const _boundBetweenErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_boundBetweenErrMsg')

_boundBetweenErrMsg(0, 42, true, true)     //=> 'must be >= 0 and <= 42'

_boundBetweenErrMsg(0, 42, false, false)   //=> 'must be > 0 and < 42'

_boundLowerErrMsgMisc

const _boundLowerErrMsg = require('@eluvio/elv-js-helpers/Misc/_boundLowerErrMsg')
a → Boolean → String
Parameters
  • AnylowerBound
  • Booleaninclusive

    Whether values are allowed to equal lowerBound

  • Returns:String

Returns a description of a lower bound condition

'use strict'
const _boundLowerErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_boundLowerErrMsg')

_boundLowerErrMsg(42, true)   //=> 'must be >= 42'

_boundLowerErrMsg(42, false)  //=> 'must be > 42'

_boundUpperErrMsgMisc

const _boundUpperErrMsg = require('@eluvio/elv-js-helpers/Misc/_boundUpperErrMsg')
a → Boolean → String
Parameters
  • AnyupperBound
  • Booleaninclusive

    Whether values are allowed to equal upperBound

  • Returns:String

Returns a description of an upper bound condition

'use strict'
const _boundUpperErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_boundUpperErrMsg')

_boundUpperErrMsg(42, true)   //=> 'must be <= 42'

_boundUpperErrMsg(42, false)  //=> 'must be < 42'

_objBadKeyErrMsgModelAssertion

const _objBadKeyErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_objBadKeyErrMsg')
Model → ((Boolean, String) → String)
Parameters
  • ModelkeyModel

    The Model to check keys against

  • Returns:function

    Constructs an error message for failed key

Returns a function to be called by ObjectModel to construct an error message for a key that failed to validate against specified Model

'use strict'
const _objBadKeyErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_objBadKeyErrMsg')

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')
const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')
const passesModelCheck = require('@eluvio/elv-js-helpers/Boolean/passesModelCheck')

const NoBlankKeysObjModel = defBasicModel('NoBlankKeysObj', Object).extend()
  .assert(
    passesModelCheck(NonBlankStrModel),
    _objBadKeyErrMsg(NonBlankStrModel)
  )

NoBlankKeysObjModel({'  ': 3})                      //=> EXCEPTION: 'invalid property name "  " (is not a valid NonBlankString)'

_objBadValErrMsgModelAssertion

const _objBadValErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_objBadValErrMsg')
Model → ((Boolean, String) → String)
Parameters
  • ModelvalueModel

    The Model to check values against

  • Returns:function

    Constructs an error message for failed value

Returns a function to be called by ObjectModel to construct an error message for a value that failed to validate against specified Model

'use strict'
const passesModelCheck = require('@eluvio/elv-js-helpers/Boolean/passesModelCheck')

const _objBadValErrMsg = require('@eluvio/elv-js-helpers/ModelAssertion/_objBadValErrMsg')

const NonBlankStrModel = require('@eluvio/elv-js-helpers/Model/NonBlankStrModel')

const defBasicModel = require('@eluvio/elv-js-helpers/ModelFactory/defBasicModel')

const NoBlankValuesObjModel = defBasicModel('NoBlankValuesObj', Object).extend()
  .assert(
    passesModelCheck(NonBlankStrModel),
    _objBadValErrMsg(NonBlankStrModel)
  )

NoBlankValuesObjModel({foo: '  '})        //=> EXCEPTION: 'key "foo" points to a value that is an invalid NonBlankString (NonBlankString: Value must not be a blank string (got: "  "))'

_strOrRegExSrcConversion

const _strOrRegExSrc = require('@eluvio/elv-js-helpers/Conversion/_strOrRegExSrc')
a → String | EXCEPTION
Parameters
  • Anyx

    The value to inspect

  • Returns:String

If input value is a regular expression, returns the source (definition) of the expression. If input is a string, returns the string, escaped so that it can be used as to construct an exact match regexp. Otherwise throws an exception.

'use strict'
const _strOrRegExSrc = require('@eluvio/elv-js-helpers/Conversion/_strOrRegExSrc')

const RE_UUID_LOWER_CASE = require('@eluvio/elv-js-helpers/Validation/RE_UUID_LOWER_CASE')

_strOrRegExSrc(RE_UUID_LOWER_CASE)  //=> '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'

_strOrRegExSrc('foo')               //=> 'foo'

_strOrRegExSrc(3)                   //=> EXCEPTION: 'Value is not a RegExp or string (3)'

_throwIfNotErrValidation

const _throwIfNotErr = require('@eluvio/elv-js-helpers/Validation/_throwIfNotErr')
Err a | b → Err a | THROW
Parameters
  • Anyx

    the value to check

  • Returns:Err

Throws an exception if anything but a Crocks Err is passed in. Otherwise does nothing and returns the Err

'use strict'
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const _throwIfNotErr = require('@eluvio/elv-js-helpers/Validation/_throwIfNotErr')

_throwIfNotErr(42)          //=> EXCEPTION: 'Expected an Err, got: Number (42)'

_throwIfNotErr(Ok(42))      //=> EXCEPTION: 'Expected an Err, got: Ok (Ok 42)'

// No exception thrown:
_throwIfNotErr(Err('foo'))

_throwIfNotResultValidation

const _throwIfNotResult = require('@eluvio/elv-js-helpers/Validation/_throwIfNotResult')
Result a | b → Result a | THROW
Parameters
  • Anyx

    the value to check

  • Returns:Result

Throws an exception if anything but a Crocks Result is passed in. Otherwise returns the Result unchanged.

'use strict'
const _throwIfNotResult = require('@eluvio/elv-js-helpers/Validation/_throwIfNotResult')

const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

 _throwIfNotResult(42)                      //=> EXCEPTION: 'Expected a value of type Result, got: Number (42)'
_throwIfNotResult(Err(['42'])).inspect()    //=> 'Err [ "42" ]'
_throwIfNotResult(Ok(42)).inspect()         //=> 'Ok 42'

_typeWithOkErrValidation

const _typeWithOkErr = require('@eluvio/elv-js-helpers/Validation/_typeWithOkErr')
a → Boolean
Parameters
  • Returns:Boolean

Returns "Ok" if passed a Crocks Ok. Returns "Err" if passed a Crocks Err. Returns type(x) if passed anything else https://github.com/evilsoft/crocks/blob/master/src/core/type.js

Enables distinguishing between 'Err' and 'Ok' when examining Result instances.

NOTE: Use kind() if you need to check type of anything other than a Crocks Result instance (i.e. anything other than an Ok or Err).

'use strict'
const Err = require('@eluvio/elv-js-helpers/ADT/Err')
const Ok = require('@eluvio/elv-js-helpers/ADT/Ok')

const _typeWithOkErr = require('@eluvio/elv-js-helpers/Validation/_typeWithOkErr')

_typeWithOkErr(Err(['invalid query'])) //=> "Err"

_typeWithOkErr(Ok(42))                 //=> "Ok"

// use kind() instead to check values other than Ok/Err!
_typeWithOkErr('foo')                  //=> "String"