"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _propertyExpr = require("property-expr");

var prefixes = {
  context: '$',
  value: '.'
};

var Reference =
/*#__PURE__*/
function () {
  function Reference(key, options) {
    if (options === void 0) {
      options = {};
    }

    if (typeof key !== 'string') throw new TypeError('ref must be a string, got: ' + key);
    this.key = key.trim();
    if (key === '') throw new TypeError('ref must be a non-empty string');
    this.isContext = this.key[0] === prefixes.context;
    this.isValue = this.key[0] === prefixes.value;
    this.isSibling = !this.isContext && !this.isValue;
    var prefix = this.isContext ? prefixes.context : this.isValue ? prefixes.value : '';
    this.path = this.key.slice(prefix.length);
    this.getter = this.path && (0, _propertyExpr.getter)(this.path, true);
    this.map = options.map;
  }

  var _proto = Reference.prototype;

  _proto.getValue = function getValue(options) {
    var result = this.isContext ? options.context : this.isValue ? options.value : options.parent;
    if (this.getter) result = this.getter(result || {});
    if (this.map) result = this.map(result);
    return result;
  };

  _proto.cast = function cast(value, options) {
    return this.getValue((0, _extends2.default)({}, options, {
      value: value
    }));
  };

  _proto.resolve = function resolve() {
    return this;
  };

  _proto.describe = function describe() {
    return {
      type: 'ref',
      key: this.key
    };
  };

  _proto.toString = function toString() {
    return "Ref(" + this.key + ")";
  };

  Reference.isRef = function isRef(value) {
    return value && value.__isYupRef;
  };

  return Reference;
}();

exports.default = Reference;
Reference.prototype.__isYupRef = true;
module.exports = exports["default"];