"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = ObjectSchema; var _taggedTemplateLiteralLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteralLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _has = _interopRequireDefault(require("lodash/has")); var _snakeCase2 = _interopRequireDefault(require("lodash/snakeCase")); var _camelCase2 = _interopRequireDefault(require("lodash/camelCase")); var _mapKeys = _interopRequireDefault(require("lodash/mapKeys")); var _mapValues = _interopRequireDefault(require("lodash/mapValues")); var _propertyExpr = require("property-expr"); var _mixed = _interopRequireDefault(require("./mixed")); var _locale = require("./locale.js"); var _sortFields = _interopRequireDefault(require("./util/sortFields")); var _sortByKeyOrder = _interopRequireDefault(require("./util/sortByKeyOrder")); var _inherits = _interopRequireDefault(require("./util/inherits")); var _makePath = _interopRequireDefault(require("./util/makePath")); var _runValidations = _interopRequireWildcard(require("./util/runValidations")); function _templateObject2() { var data = (0, _taggedTemplateLiteralLoose2.default)(["", ".", ""]); _templateObject2 = function _templateObject2() { return data; }; return data; } function _templateObject() { var data = (0, _taggedTemplateLiteralLoose2.default)(["", ".", ""]); _templateObject = function _templateObject() { return data; }; return data; } var isObject = function isObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; }; function unknown(ctx, value) { var known = Object.keys(ctx.fields); return Object.keys(value).filter(function (key) { return known.indexOf(key) === -1; }); } function ObjectSchema(spec) { var _this2 = this; if (!(this instanceof ObjectSchema)) return new ObjectSchema(spec); _mixed.default.call(this, { type: 'object', default: function _default() { var _this = this; if (!this._nodes.length) return undefined; var dft = {}; this._nodes.forEach(function (key) { dft[key] = _this.fields[key].default ? _this.fields[key].default() : undefined; }); return dft; } }); this.fields = Object.create(null); this._nodes = []; this._excludedEdges = []; this.withMutation(function () { _this2.transform(function coerce(value) { if (typeof value === 'string') { try { value = JSON.parse(value); } catch (err) { value = null; } } if (this.isType(value)) return value; return null; }); if (spec) { _this2.shape(spec); } }); } (0, _inherits.default)(ObjectSchema, _mixed.default, { _typeCheck: function _typeCheck(value) { return isObject(value) || typeof value === 'function'; }, _cast: function _cast(_value, options) { var _this3 = this; if (options === void 0) { options = {}; } var value = _mixed.default.prototype._cast.call(this, _value, options); //should ignore nulls here if (value === undefined) return this.default(); if (!this._typeCheck(value)) return value; var fields = this.fields; var strip = this._option('stripUnknown', options) === true; var props = this._nodes.concat(Object.keys(value).filter(function (v) { return _this3._nodes.indexOf(v) === -1; })); var intermediateValue = {}; // is filled during the transform below var innerOptions = (0, _extends2.default)({}, options, { parent: intermediateValue, __validating: false }); var isChanged = false; props.forEach(function (prop) { var field = fields[prop]; var exists = (0, _has.default)(value, prop); if (field) { var fieldValue; var strict = field._options && field._options.strict; // safe to mutate since this is fired in sequence innerOptions.path = (0, _makePath.default)(_templateObject(), options.path, prop); innerOptions.value = value[prop]; field = field.resolve(innerOptions); if (field._strip === true) { isChanged = isChanged || prop in value; return; } fieldValue = !options.__validating || !strict ? field.cast(value[prop], innerOptions) : value[prop]; if (fieldValue !== undefined) intermediateValue[prop] = fieldValue; } else if (exists && !strip) intermediateValue[prop] = value[prop]; if (intermediateValue[prop] !== value[prop]) isChanged = true; }); return isChanged ? intermediateValue : value; }, _validate: function _validate(_value, opts) { var _this4 = this; if (opts === void 0) { opts = {}; } var endEarly, recursive; var sync = opts.sync; var errors = []; var originalValue = opts.originalValue != null ? opts.originalValue : _value; endEarly = this._option('abortEarly', opts); recursive = this._option('recursive', opts); opts = (0, _extends2.default)({}, opts, { __validating: true, originalValue: originalValue }); return _mixed.default.prototype._validate.call(this, _value, opts).catch((0, _runValidations.propagateErrors)(endEarly, errors)).then(function (value) { if (!recursive || !isObject(value)) { // only iterate though actual objects if (errors.length) throw errors[0]; return value; } originalValue = originalValue || value; var validations = _this4._nodes.map(function (key) { var path = (0, _makePath.default)(_templateObject2(), opts.path, key); var field = _this4.fields[key]; var innerOptions = (0, _extends2.default)({}, opts, { path: path, parent: value, originalValue: originalValue[key] }); if (field && field.validate) { // inner fields are always strict: // 1. this isn't strict so the casting will also have cast inner values // 2. this is strict in which case the nested values weren't cast either innerOptions.strict = true; return field.validate(value[key], innerOptions); } return Promise.resolve(true); }); return (0, _runValidations.default)({ sync: sync, validations: validations, value: value, errors: errors, endEarly: endEarly, path: opts.path, sort: (0, _sortByKeyOrder.default)(_this4.fields) }); }); }, concat: function concat(schema) { var next = _mixed.default.prototype.concat.call(this, schema); next._nodes = (0, _sortFields.default)(next.fields, next._excludedEdges); return next; }, shape: function shape(schema, excludes) { if (excludes === void 0) { excludes = []; } var next = this.clone(); var fields = (0, _extends2.default)(next.fields, schema); next.fields = fields; if (excludes.length) { if (!Array.isArray(excludes[0])) excludes = [excludes]; var keys = excludes.map(function (_ref) { var first = _ref[0], second = _ref[1]; return first + "-" + second; }); next._excludedEdges = next._excludedEdges.concat(keys); } next._nodes = (0, _sortFields.default)(fields, next._excludedEdges); return next; }, from: function from(_from, to, alias) { var fromGetter = (0, _propertyExpr.getter)(_from, true); return this.transform(function (obj) { if (obj == null) return obj; var newObj = obj; if ((0, _has.default)(obj, _from)) { newObj = (0, _extends2.default)({}, obj); if (!alias) delete newObj[_from]; newObj[to] = fromGetter(obj); } return newObj; }); }, noUnknown: function noUnknown(noAllow, message) { if (noAllow === void 0) { noAllow = true; } if (message === void 0) { message = _locale.object.noUnknown; } if (typeof noAllow === 'string') { message = noAllow; noAllow = true; } var next = this.test({ name: 'noUnknown', exclusive: true, message: message, test: function test(value) { return value == null || !noAllow || unknown(this.schema, value).length === 0; } }); if (noAllow) next._options.stripUnknown = true; return next; }, transformKeys: function transformKeys(fn) { return this.transform(function (obj) { return obj && (0, _mapKeys.default)(obj, function (_, key) { return fn(key); }); }); }, camelCase: function camelCase() { return this.transformKeys(_camelCase2.default); }, snakeCase: function snakeCase() { return this.transformKeys(_snakeCase2.default); }, constantCase: function constantCase() { return this.transformKeys(function (key) { return (0, _snakeCase2.default)(key).toUpperCase(); }); }, describe: function describe() { var base = _mixed.default.prototype.describe.call(this); base.fields = (0, _mapValues.default)(this.fields, function (value) { return value.describe(); }); return base; } }); module.exports = exports["default"];