All files / packages/design-system/shared/utils either.js

87.5% Statements 28/32
100% Branches 2/2
89.47% Functions 17/19
86.66% Lines 26/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112                                        18x 18x 18x               1x       1x       1x       5x         1x           8x 720x           1x       1x                 1x                 1x       7x 196x   147x       9x       2x   2x 2x   1x         3x 3x 1x 1x  
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
 
/**
 * Minimal Either monad — a local, dependency-free replacement for the
 * deprecated `data.either` package.
 *
 * Implements exactly the surface the build scripts and library consumers use:
 *   constructors: Right, Left, of, fromNullable, try
 *   instance:     map, chain, fold, get, getOrElse, orElse, isRight, isLeft
 *
 * `dist/__internal/slds.umd.js` returns these to outside consumers such as
 * design-system-site, which call `.get()` (e.g. `slds.component(id).get()`).
 *
 * Semantics mirror data.either: `map`/`chain` only transform a Right and pass a
 * Left through untouched; `fold(onLeft, onRight)` collapses either side.
 */
 
class Right {
  constructor(value) {
    this.value = value;
    this.isRight = true;
    this.isLeft = false;
  }
 
  map(fn) {
    return new Right(fn(this.value));
  }
 
  chain(fn) {
    return fn(this.value);
  }
 
  fold(_onLeft, onRight) {
    return onRight(this.value);
  }
 
  get() {
    return this.value;
  }
 
  getOrElse(_defaultValue) {
    return this.value;
  }
 
  // A Right short-circuits orElse (there is nothing to recover from).
  orElse(_fn) {
    return this;
  }
}
 
class Left {
  constructor(value) {
    this.value = value;
    this.isRight = false;
    this.isLeft = true;
  }
 
  // map/chain are no-ops on a Left — the failure is carried through unchanged.
  map(_fn) {
    return this;
  }
 
  chain(_fn) {
    return this;
  }
 
  fold(onLeft, _onRight) {
    return onLeft(this.value);
  }
 
  // Same error data.either throws; use getOrElse/fold to handle a Left.
  get() {
    throw new TypeError("Can't extract the value of a Left(a).");
  }
 
  getOrElse(defaultValue) {
    return defaultValue;
  }
 
  // orElse lets a caller recover from a Left by supplying a new Either.
  orElse(fn) {
    return fn(this.value);
  }
}
 
const right = (value) => new Right(value);
const left = (value) => new Left(value);
 
const Either = {
  Right: right,
  Left: left,
  of: right,
  fromNullable: (value) => (value == null ? new Left(value) : new Right(value)),
  // `try(fn)` returns a function that runs `fn`, wrapping the result in a Right
  // or any thrown error in a Left. Matches data.either's curried form.
  try:
    (fn) =>
    (...args) => {
      try {
        return new Right(fn(...args));
      } catch (error) {
        return new Left(error);
      }
    },
};
 
module.exports = Either;
module.exports.Right = right;
module.exports.Left = left;
module.exports.default = Either;