UNPKG

react-easel

Version:

Widget to dynamically build forms using simple-schema and uniforms

1,564 lines (1,245 loc) 1.24 MB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react")); else if(typeof define === 'function' && define.amd) define("react-formbuilder", ["react"], factory); else if(typeof exports === 'object') exports["react-formbuilder"] = factory(require("react")); else root["react-formbuilder"] = factory(root["React"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 214); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_0__; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _assign = __webpack_require__(218); var _assign2 = _interopRequireDefault(_assign); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _assign2.default || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Copyright (c) 2016 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ /* global define */ (function () { 'use strict'; var hasOwn = {}.hasOwnProperty; function classNames () { var classes = []; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (!arg) continue; var argType = typeof arg; if (argType === 'string' || argType === 'number') { classes.push(arg); } else if (Array.isArray(arg)) { classes.push(classNames.apply(null, arg)); } else if (argType === 'object') { for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes.push(key); } } } } return classes.join(' '); } if (typeof module !== 'undefined' && module.exports) { module.exports = classNames; } else if (true) { // register as 'classnames', consistent with npm package name !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () { return classNames; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else { window.classNames = classNames; } }()); /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _classCallCheck2 = __webpack_require__(4); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = __webpack_require__(9); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = __webpack_require__(7); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _get2 = __webpack_require__(42); var _get3 = _interopRequireDefault(_get2); var _inherits2 = __webpack_require__(6); var _inherits3 = _interopRequireDefault(_inherits2); exports.default = connectField; var _react = __webpack_require__(0); var _BaseField = __webpack_require__(27); var _BaseField2 = _interopRequireDefault(_BaseField); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var identity = function identity(x) { return x; }; function connectField(component) { var _class, _temp; var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$baseField = _ref.baseField, baseField = _ref$baseField === undefined ? _BaseField2.default : _ref$baseField, _ref$mapProps = _ref.mapProps, mapProps = _ref$mapProps === undefined ? identity : _ref$mapProps, ensureValue = _ref.ensureValue, includeInChain = _ref.includeInChain, includeParent = _ref.includeParent, initialValue = _ref.initialValue; return _temp = _class = function (_baseField) { (0, _inherits3.default)(_class, _baseField); function _class() { (0, _classCallCheck3.default)(this, _class); var _this = (0, _possibleConstructorReturn3.default)(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments)); _this.options.includeInChain = includeInChain === undefined ? true : includeInChain; _this.options.initialValue = initialValue === undefined ? true : initialValue; if (ensureValue !== undefined) _this.options.ensureValue = ensureValue; if (includeParent !== undefined) _this.options.includeParent = includeParent; return _this; } (0, _createClass3.default)(_class, [{ key: 'getChildContextName', value: function getChildContextName() { return this.options.includeInChain ? (0, _get3.default)(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'getChildContextName', this).call(this) : this.context.uniforms.name; } }, { key: 'componentWillMount', value: function componentWillMount() { if (this.options.initialValue) { var props = this.getFieldProps(undefined, { ensureValue: false, explicitInitialValue: true, includeParent: false }); // https://github.com/vazco/uniforms/issues/52 // If field is initially rendered with value, we treat it as an initial value. if (this.props.value !== undefined && this.props.value !== props.value) { props.onChange(this.props.value); return; } if (props.required && props.initialValue !== undefined && props.value === undefined) { props.onChange(props.initialValue); } } } }, { key: 'render', value: function render() { return (0, _react.createElement)(component, mapProps(this.getFieldProps())); } }]); return _class; }(baseField), _class.displayName = '' + (component.displayName || component.name) + (baseField.displayName || baseField.name), _temp; } /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; exports.default = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; exports.default = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _setPrototypeOf = __webpack_require__(223); var _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf); var _create = __webpack_require__(219); var _create2 = _interopRequireDefault(_create); var _typeof2 = __webpack_require__(56); var _typeof3 = _interopRequireDefault(_typeof2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : (0, _typeof3.default)(superClass))); } subClass.prototype = (0, _create2.default)(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) _setPrototypeOf2.default ? (0, _setPrototypeOf2.default)(subClass, superClass) : subClass.__proto__ = superClass; }; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _typeof2 = __webpack_require__(56); var _typeof3 = _interopRequireDefault(_typeof2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && ((typeof call === "undefined" ? "undefined" : (0, _typeof3.default)(call)) === "object" || typeof call === "function") ? call : self; }; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ if (false) { var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) || 0xeac7; var isValidElement = function(object) { return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE; }; // By explicitly using `prop-types` you are opting into new development behavior. // http://fb.me/prop-types-in-prod var throwOnDirectAccess = true; module.exports = require('./factoryWithTypeCheckers')(isValidElement, throwOnDirectAccess); } else { // By explicitly using `prop-types` you are opting into new production behavior. // http://fb.me/prop-types-in-prod module.exports = __webpack_require__(404)(); } /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _defineProperty = __webpack_require__(220); var _defineProperty2 = _interopRequireDefault(_defineProperty); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; (0, _defineProperty2.default)(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /***/ }), /* 10 */ /***/ (function(module, exports) { var core = module.exports = {version: '2.4.0'}; if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ /** * Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */ var invariant = function(condition, format, a, b, c, d, e, f) { if (false) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } } if (!condition) { var error; if (format === undefined) { error = new Error( 'Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.' ); } else { var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( format.replace(/%s/g, function() { return args[argIndex++]; }) ); error.name = 'Invariant Violation'; } error.framesToPop = 1; // we don't care about invariant's own frame throw error; } }; module.exports = invariant; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = filterDOMProps; var unwantedProps = [ // These props are provided by BaseField 'changed', 'changedMap', 'disabled', 'error', 'errorMessage', 'field', 'fieldType', 'fields', 'findError', 'findField', 'findValue', 'initialCount', 'label', 'name', 'onChange', 'parent', 'placeholder', 'showInlineError', 'value', // This is used by AutoField 'component']; // Some benchmarks // https://albertxing.com/stool/#bb5cbc0441ad7ac47602694f6c7183b4 function filterDOMProps(props) { var filteredProps = {}; for (var prop in props) { if (unwantedProps.indexOf(prop) === -1) { filteredProps[prop] = props[prop]; } } return filteredProps; } // Bridges have to register additional props filterDOMProps.register = function () { for (var _len = arguments.length, props = Array(_len), _key = 0; _key < _len; _key++) { props[_key] = arguments[_key]; } props.forEach(function (prop) { if (unwantedProps.indexOf(prop) === -1) { unwantedProps.push(prop); } }); }; // It might be handy at some point filterDOMProps.registered = unwantedProps; /***/ }), /* 13 */ /***/ (function(module, exports) { /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; module.exports = isArray; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = joinName; function joinName() { for (var _len = arguments.length, parts = Array(_len), _key = 0; _key < _len; _key++) { parts[_key] = arguments[_key]; } var name = parts.reduce(function (parts, part) { return part || part === 0 ? parts.concat(typeof part === 'string' ? part.split('.') : part) : parts; }, []); return parts[0] === null ? name.map(function (part) { return part.toString(); }) : name.join('.'); } /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { var store = __webpack_require__(88)('wks') , uid = __webpack_require__(59) , Symbol = __webpack_require__(23).Symbol , USE_SYMBOL = typeof Symbol == 'function'; var $exports = module.exports = function(name){ return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); }; $exports.store = store; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationContext = exports.SimpleSchema = exports.schemaDefinitionOptions = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extend2 = __webpack_require__(143); var _extend3 = _interopRequireDefault(_extend2); var _mongoObject = __webpack_require__(35); var _mongoObject2 = _interopRequireDefault(_mongoObject); var _underscore = __webpack_require__(19); var _underscore2 = _interopRequireDefault(_underscore); var _messageBox = __webpack_require__(403); var _messageBox2 = _interopRequireDefault(_messageBox); var _clone = __webpack_require__(126); var _clone2 = _interopRequireDefault(_clone); var _humanize = __webpack_require__(445); var _humanize2 = _interopRequireDefault(_humanize); var _ValidationContext = __webpack_require__(439); var _ValidationContext2 = _interopRequireDefault(_ValidationContext); var _SimpleSchemaGroup = __webpack_require__(438); var _SimpleSchemaGroup2 = _interopRequireDefault(_SimpleSchemaGroup); var _regExp = __webpack_require__(190); var _regExp2 = _interopRequireDefault(_regExp); var _clean2 = __webpack_require__(189); var _clean3 = _interopRequireDefault(_clean2); var _expandShorthand = __webpack_require__(444); var _expandShorthand2 = _interopRequireDefault(_expandShorthand); var _utility = __webpack_require__(51); var _defaultMessages = __webpack_require__(442); var _defaultMessages2 = _interopRequireDefault(_defaultMessages); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // Exported for tests var schemaDefinitionOptions = exports.schemaDefinitionOptions = ['type', 'label', 'optional', 'required', 'autoValue', 'defaultValue']; var oneOfProps = ['type', 'min', 'max', 'minCount', 'maxCount', 'allowedValues', 'exclusiveMin', 'exclusiveMax', 'regEx', 'custom', 'blackbox', 'trim']; var propsThatCanBeFunction = ['label', 'optional', 'min', 'max', 'minCount', 'maxCount', 'allowedValues', 'exclusiveMin', 'exclusiveMax', 'regEx']; var SimpleSchema = function () { function SimpleSchema() { var schema = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, SimpleSchema); this.pick = getPickOrOmit('pick'); this.omit = getPickOrOmit('omit'); // Stash the options object this._constructorOptions = _extends({}, options); if (this._constructorOptions.humanizeAutoLabels !== false) this._constructorOptions.humanizeAutoLabels = true; // Custom validators for this instance this._validators = []; this._docValidators = []; // Named validation contexts this._validationContexts = {}; // Schema-level defaults for cleaning this._cleanOptions = _extends({ filter: true, autoConvert: true, removeEmptyStrings: true, trimStrings: true, getAutoValues: true, removeNullsFromArrays: false, extendAutoValueContext: {} }, options.clean); // Clone, expanding shorthand, and store the schema object in this._schema this._schema = {}; this.extend(schema); // Define default validation error messages this.messageBox = new _messageBox2.default((0, _clone2.default)(_defaultMessages2.default)); this.version = SimpleSchema.version; } _createClass(SimpleSchema, [{ key: 'findFirstAncestorSimpleSchema', value: function findFirstAncestorSimpleSchema(key, func) { var _this = this; var genericKey = _mongoObject2.default.makeKeyGeneric(key); var foundSchema = false; (0, _utility.forEachKeyAncestor)(genericKey, function (ancestor) { if (foundSchema) return; // skip remaining once we've found it var def = _this._schema[ancestor]; if (!def) return; def.type.definitions.forEach(function (typeDef) { if (typeDef.type instanceof SimpleSchema) { func(typeDef.type, ancestor, genericKey.slice(ancestor.length + 1)); foundSchema = true; } }); }); return foundSchema; } /** * Returns whether the obj is a SimpleSchema object. * @param {Object} [obj] An object to test * @returns {Boolean} True if the given object appears to be a SimpleSchema instance */ }, { key: 'schema', /** * @param {String} [key] One specific or generic key for which to get the schema. * @returns {Object} The entire schema object or just the definition for one key. * * Note that this returns the raw, unevaluated definition object. Use `getDefinition` * if you want the evaluated definition, where any properties that are functions * have been run to produce a result. */ value: function schema(key) { if (!key) return this._schema; var genericKey = _mongoObject2.default.makeKeyGeneric(key); var keySchema = this._schema[genericKey]; // If not defined in this schema, see if it's defined in a subschema if (!keySchema) { this.findFirstAncestorSimpleSchema(key, function (simpleSchema, ancestor, subSchemaKey) { keySchema = simpleSchema.schema(subSchemaKey); }); } return keySchema; } /** * @returns {Object} The entire schema object with subschemas merged. This is the * equivalent of what schema() returned in SimpleSchema < 2.0 * * Note that this returns the raw, unevaluated definition object. Use `getDefinition` * if you want the evaluated definition, where any properties that are functions * have been run to produce a result. */ }, { key: 'mergedSchema', value: function mergedSchema() { var mergedSchema = {}; _underscore2.default.each(this._schema, function (keySchema, key) { mergedSchema[key] = keySchema; keySchema.type.definitions.forEach(function (typeDef) { if (!SimpleSchema.isSimpleSchema(typeDef.type)) return; _underscore2.default.each(typeDef.type.mergedSchema(), function (subKeySchema, subKey) { mergedSchema[key + '.' + subKey] = subKeySchema; }); }); }); return mergedSchema; } /** * Returns the evaluated definition for one key in the schema * * @param {String} key Generic or specific schema key * @param {Array(String)} [propList] Array of schema properties you need; performance optimization * @param {Object} [functionContext] The context to use when evaluating schema options that are functions * @returns {Object} The schema definition for the requested key */ }, { key: 'getDefinition', value: function getDefinition(key, propList, functionContext) { var _this2 = this; var defs = this.schema(key); if (!defs) return; var getPropIterator = function getPropIterator(obj) { return function (val, prop) { if (Array.isArray(propList) && !_underscore2.default.contains(propList, prop)) return; // For any options that support specifying a function, evaluate the functions if (propsThatCanBeFunction.indexOf(prop) > -1 && typeof val === 'function') { obj[prop] = val.call(functionContext || {}); // Inflect label if undefined if (prop === 'label' && typeof obj[prop] !== 'string') obj[prop] = inflectedLabel(key, _this2._constructorOptions.humanizeAutoLabels); } else { obj[prop] = val; } }; }; var result = {}; _underscore2.default.each(defs, getPropIterator(result)); // Resolve all the types and convert to a normal array to make it easier // to use. if (defs.type) { result.type = defs.type.definitions.map(function (typeDef) { var newTypeDef = {}; _underscore2.default.each(typeDef, getPropIterator(newTypeDef)); return newTypeDef; }); } return result; } /** * Returns a string identifying the best guess data type for a key. For keys * that allow multiple types, the first type is used. This can be useful for * building forms. * * @param {String} key Generic or specific schema key * @returns {String} A type string. One of: * string, number, boolean, date, object, stringArray, numberArray, booleanArray, * dateArray, objectArray */ }, { key: 'getQuickTypeForKey', value: function getQuickTypeForKey(key) { var type = void 0; var fieldSchema = this.schema(key); if (!fieldSchema) return; var fieldType = fieldSchema.type.singleType; if (fieldType === String) { type = 'string'; } else if (fieldType === Number || fieldType === SimpleSchema.Integer) { type = 'number'; } else if (fieldType === Boolean) { type = 'boolean'; } else if (fieldType === Date) { type = 'date'; } else if (fieldType === Array) { var arrayItemFieldSchema = this.schema(key + '.$'); if (!arrayItemFieldSchema) return; var arrayItemFieldType = arrayItemFieldSchema.type.singleType; if (arrayItemFieldType === String) { type = 'stringArray'; } else if (arrayItemFieldType === Number || arrayItemFieldType === SimpleSchema.Integer) { type = 'numberArray'; } else if (arrayItemFieldType === Boolean) { type = 'booleanArray'; } else if (arrayItemFieldType === Date) { type = 'dateArray'; } else if (arrayItemFieldType === Object || SimpleSchema.isSimpleSchema(arrayItemFieldType)) { type = 'objectArray'; } } else if (fieldType === Object) { type = 'object'; } return type; } /** * Given a key that is an Object, returns a new SimpleSchema instance scoped to that object. * * @param {String} key Generic or specific schema key */ }, { key: 'getObjectSchema', value: function getObjectSchema(key) { var newSchemaDef = {}; var genericKey = _mongoObject2.default.makeKeyGeneric(key); var searchString = genericKey + '.'; _underscore2.default.each(this.mergedSchema(), function (val, k) { if (k.indexOf(searchString) === 0) { newSchemaDef[k.slice(searchString.length)] = val; } }); return new SimpleSchema(newSchemaDef); } // Returns an array of all the autovalue functions, including those in subschemas all the // way down the schema tree }, { key: 'autoValueFunctions', value: function autoValueFunctions() { var result = []; function addFuncs(autoValues, closestSubschemaFieldName) { _underscore2.default.each(autoValues, function (func, fieldName) { result.push({ func: func, fieldName: fieldName, closestSubschemaFieldName: closestSubschemaFieldName }); }); } addFuncs(this._autoValues, ''); _underscore2.default.each(this._schema, function (keySchema, key) { keySchema.type.definitions.forEach(function (typeDef) { if (!SimpleSchema.isSimpleSchema(typeDef.type)) return; result = result.concat(typeDef.type.autoValueFunctions().map(function (_ref) { var func = _ref.func, fieldName = _ref.fieldName, closestSubschemaFieldName = _ref.closestSubschemaFieldName; return { func: func, fieldName: key + '.' + fieldName, closestSubschemaFieldName: closestSubschemaFieldName.length ? key + '.' + closestSubschemaFieldName : key }; })); }); }); return result; } // Returns an array of all the blackbox keys, including those in subschemas }, { key: 'blackboxKeys', value: function blackboxKeys() { var blackboxKeys = this._blackboxKeys; _underscore2.default.each(this._schema, function (keySchema, key) { keySchema.type.definitions.forEach(function (typeDef) { if (!SimpleSchema.isSimpleSchema(typeDef.type)) return; typeDef.type._blackboxKeys.forEach(function (blackboxKey) { blackboxKeys.push(key + '.' + blackboxKey); }); }); }); return _underscore2.default.uniq(blackboxKeys); } // Check if the key is a nested dot-syntax key inside of a blackbox object }, { key: 'keyIsInBlackBox', value: function keyIsInBlackBox(key) { var _this3 = this; var isInBlackBox = false; (0, _utility.forEachKeyAncestor)(_mongoObject2.default.makeKeyGeneric(key), function (ancestor, remainder) { if (_this3._blackboxKeys.indexOf(ancestor) > -1) { isInBlackBox = true; } else { var testKeySchema = _this3.schema(ancestor); if (testKeySchema) { testKeySchema.type.definitions.forEach(function (typeDef) { if (!SimpleSchema.isSimpleSchema(typeDef.type)) return; if (typeDef.type.keyIsInBlackBox(remainder)) isInBlackBox = true; }); } } }); return isInBlackBox; } // Returns true if key is explicitly allowed by the schema or implied // by other explicitly allowed keys. // The key string should have $ in place of any numeric array positions. }, { key: 'allowsKey', value: function allowsKey(key) { var _this4 = this; // Loop through all keys in the schema return _underscore2.default.any(this._schemaKeys, function (loopKey) { // If the schema key is the test key, it's allowed. if (loopKey === key) return true; var fieldSchema = _this4.schema(loopKey); var compare1 = key.slice(0, loopKey.length + 2); var compare2 = compare1.slice(0, -1); // Blackbox and subschema checks are needed only if key starts with // loopKey + a dot if (compare2 !== loopKey + '.') return false; // Black box handling if (_this4._blackboxKeys.indexOf(loopKey) > -1) { // If the test key is the black box key + ".$", then the test // key is NOT allowed because black box keys are by definition // only for objects, and not for arrays. return compare1 !== loopKey + '.$'; } // Subschemas var allowed = false; var subKey = key.slice(loopKey.length + 1); fieldSchema.type.definitions.forEach(function (typeDef) { if (!SimpleSchema.isSimpleSchema(typeDef.type)) return; if (typeDef.type.allowsKey(subKey)) allowed = true; }); return allowed; }); } /** * Returns all the child keys for the object identified by the generic prefix, * or all the top level keys if no prefix is supplied. * * @param {String} [keyPrefix] The Object-type generic key for which to get child keys. Omit for * top-level Object-type keys * @returns {[[Type]]} [[Description]] */ }, { key: 'objectKeys', value: function objectKeys(keyPrefix) { if (!keyPrefix) return this._firstLevelSchemaKeys; return this._objectKeys[keyPrefix + '.'] || []; } /** * Extends this schema with another schema, key by key. * * @param {SimpleSchema|Object} schema * @returns The SimpleSchema instance (chainable) */ }, { key: 'extend', value: function extend() { var _this5 = this; var schema = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var schemaObj = void 0; if (SimpleSchema.isSimpleSchema(schema)) { schemaObj = schema._schema; // Merge the validators this._validators = this._validators.concat(schema._validators); this._docValidators = this._docValidators.concat(schema._docValidators); // Merge the clean options this._cleanOptions = (0, _extend3.default)(true, {}, this._cleanOptions, schema._cleanOptions); } else { schemaObj = (0, _expandShorthand2.default)(schema); } // Update all of the information cached on the instance _underscore2.default.each(schemaObj, function (definition, fieldName) { definition = (0, _clone2.default)(definition); standardizeDefinition(definition); // Merge/extend with any existing definition if (_this5._schema[fieldName]) { if (!_this5._schema.hasOwnProperty(fieldName)) { // fieldName is actually a method from Object itself! throw new Error(fieldName + ' key is actually the name of a method on Object, please rename it'); } _this5._schema[fieldName] = _extends({}, _this5._schema[fieldName], _underscore2.default.omit(definition, 'type')); if (definition.type) _this5._schema[fieldName].type.extend(definition.type); } else { _this5._schema[fieldName] = definition; } checkAndScrubDefinition(fieldName, _this5._schema[fieldName], _this5._constructorOptions, schemaObj); }); checkSchemaOverlap(this._schema); // Set/Reset all of these this._schemaKeys = []; this._autoValues = {}; this._blackboxKeys = []; this._firstLevelSchemaKeys = []; this._depsLabels = {}; this._objectKeys = {}; _underscore2.default.each(this._schema, function (definition, fieldName) { // Keep list of all keys for speedier checking _this5._schemaKeys.push(fieldName); // Keep list of all top level keys if (fieldName.indexOf('.') === -1) _this5._firstLevelSchemaKeys.push(fieldName); // Initialize label reactive dependency (Meteor only) if (_this5._constructorOptions.tracker) { _this5._depsLabels[fieldName] = new _this5._constructorOptions.tracker.Dependency(); } // Keep list of all blackbox keys for passing to MongoObject constructor // XXX For now if any oneOf type is blackbox, then the whole field is. _underscore2.default.every(definition.type.definitions, function (oneOfDef) { if (oneOfDef.blackbox === true) { _this5._blackboxKeys.push(fieldName); return false; // exit loop } return true; }); // Keep list of autoValue functions by key if (definition.autoValue) _this5._autoValues[fieldName] = definition.autoValue; }); // Store child keys keyed by parent. This needs to be done recursively to handle // subschemas. var setObjectKeys = function setObjectKeys(curSchema, schemaParentKey) { _underscore2.default.each(curSchema, function (definition, fieldName) { fieldName = schemaParentKey ? schemaParentKey + '.' + fieldName : fieldName; if (fieldName.indexOf('.') > -1 && fieldName.slice(-2) !== '.$') { var parentKey = fieldName.slice(0, fieldName.lastIndexOf('.')); var parentKeyWithDot = parentKey + '.'; _this5._objectKeys[parentKeyWithDot] = _this5._objectKeys[parentKeyWithDot] || []; _this5._objectKeys[parentKeyWithDot].push(fieldName.slice(fieldName.lastIndexOf('.') + 1)); } // If the current field is a nested SimpleSchema, // iterate over the child fields and cache their properties as well definition.type.definitions.forEach(function (_ref2) { var type = _ref2.type; if (SimpleSchema.isSimpleSchema(type)) { setObjectKeys(type._schema, fieldName); } }); }); }; setObjectKeys(this._schema); return this; } }, { key: 'getAllowedValuesForKey', value: function getAllowedValuesForKey(key) { // For array fields, `allowedValues` is on the array item definition if (this.allowsKey(key + '.$')) { key = key + '.$'; } var defs = this.getDefinition(key, ['allowedValues']); return defs && defs.type[0].allowedValues; } }, { key: 'newContext', value: function newContext() { return new _ValidationContext2.default(this); } }, { key: 'namedContext', value: function namedContext(name) { if (typeof name !== 'string') name = 'default'; if (!this._validationContexts[name]) { this._validationContexts[name] = new SimpleSchema.ValidationContext(this); } return this._validationContexts[name]; } }, { key: 'addValidator', value: function addValidator(func) { this._validators.push(func); } }, { key: 'addDocValidator', value: function addDocValidator(func) { this._docValidators.push(func); } /** * @param obj {Object|Object[]} Object or array of objects to validate. * @param [options] {Object} Same options object that ValidationContext#validate takes * * Throws an Error with name `ClientError` and `details` property containing the errors. */ }, { key: 'validate', value: function validate(obj, options) { var _this6 = this; // For Meteor apps, `check` option can be passed to silence audit-argument-checks if (typeof this._constructorOptions.check === 'function') { // Call check but ignore the error try { this._constructorOptions.check(obj); } catch (e) {/* ignore error */} } // obj can be an array, in which case we validate each object in it and // throw as soon as one has an error var objects = Array.isArray(obj) ? obj : [obj]; objects.forEach(function (oneObj) { var validationContext = _this6.newContext(); var isValid = validationContext.validate(oneObj, options); if (isValid) return; var errors = validationContext.validationErrors(); // In order for the message at the top of the stack trace to be useful, // we set it to the first validation error message. var message = _this6.messageForError(errors[0]); var error = new Error(message); error.name = error.errorType = 'ClientError'; error.error = 'validation-error'; // Add meaningful error messages for each validation error. // Useful for display messages when using 'mdg:validated-method'. error.details = errors.map(function (errorDetail) { return _extends({}, errorDetail, { message: _this6.messageForError(errorDetail) }); }); // The primary use for the validationErrorTransform is to convert the // vanilla Error into a Meteor.Error until DDP is able to pass // vanilla errors back to the client. if (typeof SimpleSchema.validationErrorTransform === 'function') { throw SimpleSchema.validationErrorTransform(error); } else { throw error; } }); } /** * @param obj {Object} Object to validate. * @param [options] {Object} Same options object that ValidationContext#validate takes * * Returns a Promise that resolves with the errors */ }, { key: 'validateAndReturnErrorsPromise', value: function validateAndReturnErrorsPromise(obj, options) { var _this7 = this; var validationContext = this.newContext(); var isValid = validationContext.validate(obj, options); if (isValid) return Promise.resolve([]); // Add the `message` prop var errors = validationContext.validationErrors().map(function (errorDetail) { return _extends({}, errorDetail, { message: _this7.messageForError(errorDetail) }); }); return Promise.resolve(errors); } }, { key: 'validator', value: function validator() { var _this8 = this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return function (obj) { var optionsClone = _extends({}, options); if (options.clean === true) { // Do this here and pass into both functions for better performance optionsClone.mongoObject = new _mongoObject2.default(obj, _this8.blackboxKeys()); _this8.clean(obj, optionsClone); } if (options.returnErrorsPromise) { return _this8.validateAndReturnErrorsPromise(obj, optionsClone); } return _this8.validate(obj, optionsClone); }; } }, { key: 'getFormValidator', value: function getFormValidator() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return this.validator(_extends({}, options, { returnErrorsPromise: true })); } }, { key: 'clean', value: function clean() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _clean3.default.apply(undefined, [this].concat(args)); } /** * Change schema labels on the fly, causing mySchema.label computation * to rerun. Useful when the user changes the language. * * @param {Object} labels A dictionary of all the new label values, by schema key. */ }, { key: 'labels', value: function labels(_labels) { var _this9 = this; _underscore2.default.each(_labels, function (label, key) { if (typeof label !== 'string' && typeof label !== 'function') return; if (!_this9._schema.hasOwnProperty(key)) return; _this9._schema[key].label = label; _this9._depsLabels[key] && _this9._depsLabels[key].changed(); }); } /** * Gets a field's label or all field labels reactively. * * @param {String} [key] The schema key, specific or generic. * Omit this argument to get a dictionary of all labels. * @returns {String} The label */ }, { key: 'label', value: function label(key) { var _this10 = this; // Get all labels if (key === null || key === undefined) { var result = {}; _underscore2.default.each(this._schemaKeys, function (schemaKey) { result[schemaKey] = _this10.label(schemaKey); }); return result; } // Get label for one field var def = this.getDefinition(key, ['label']); if (!def) return null; var genericKey = _mongoObject2.default.makeKeyGeneric(key); this._depsLabels[genericKey] && this._depsLabels[genericKey].depend(); return def.label; } /** * Gets a field's property * * @param {String} [key] The schema key, specific or generic. * Omit this argument to get a dictionary of all labels. * @param {String} [prop] Name of the property to get. * * @returns {any} The property value */ }, { key: 'get', value: function get(key, prop) { var def = this.getDefinition(key, ['type', prop]); if (!def) return undefined; if (_underscore2.default.contains(schemaDefinitionOptions, prop)) { return def[prop]; } return (def.type.find(function (props) { return props[prop]; }) || {})[prop]; } // shorthand for getting defaultValue }, { key: 'defaultValue', value: function defaultValue(key) { return this.get(key, 'defaultValue'); } // Returns a string message for the given error type and key. Passes through // to message-box pkg. }, { key: 'messageForError', value: function messageForError(errorInfo) { var name = errorInfo.name; return this.messageBox.message(errorInfo, { context: { key: name, // backward compatibility // The call to this.label() establishes a reactive dependency, too label: this.label(name) } }); } /** * @method SimpleSchema#pick * @param {[fields]} The list of fields to pick to instantiate the subschema * @returns {SimpleSchema} The subschema */ /** * @method SimpleSchema#omit * @param {[fields]} The list of fields to omit to instantiate the subschema * @returns {SimpleSchema} The subschema */ }], [{ key: 'isSimpleSchema', value: function isSimpleSchema(obj) { return obj && (obj instanceof SimpleSchema || obj._schema); } }, { key: 'extendOptions', // If you need to allow properties other than those listed above, call this from your app or package value: function extendOptions(options) { // For backwards compatibility we still take an object here, but we only care about the names if (!Array.isArray(options)) options = Object.keys(options); options.forEach(function (option) { schemaDefinitionOptions.push(option); }); } }, { key: 'defineValidationErrorTransform', value: function defineValidationErrorTransform(transform) { if (typeof transform !== 'function') { throw new Error('SimpleSchema.defineValidationErrorTransform must be passed a function that accepts an Error and returns an Error'); } SimpleSchema.validationErrorTransform = transform; } }, { key: 'validate', value: function validate(obj, schema, options) { // Allow passing just the schema object if (!SimpleSchema.isSimpleSchema(schema)) { schema = new SimpleSchema(schema); } return schema.validate(obj, options); } }, { key: 'oneOf', value: function oneOf() { for (var _len2 = arguments.length, definitions = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { definitions[_key2] = arguments[_key2]; } return new (Function.prototype.bind.apply(_SimpleSchemaGroup2.default, [null].concat(definitions)))(); } // Global custom validators }, { key: 'addValidator', value: function addValidator(func) { SimpleSchema._validators.push(func); } }, { key: 'addDocValidator', value: function addDocValidator(func) { SimpleSchema._docValidators.push(func); } // Backwards compatibility }]); return SimpleSchema; }(); /* * PRIVATE */ // Throws an error if any fields are `type` SimpleSchema but then also // have subfields defined outside of that. SimpleSchema.version = 2; SimpleSchema.RegEx = _regExp2.default; SimpleSchema._validators = []; SimpleSchema._docValidators = []; SimpleSchema.ErrorTypes = { REQUIRED: 'required', MIN_STRING: 'minString', MAX_STRING: 'maxString', MIN_NUMBER: 'minNumber', MAX_NUMBER: 'maxNumber', MIN_NUMBER_EXCLUSIVE: 'minNumberExclusive', MAX_NUMBER_EXCLUSIVE: 'maxNumberExclusive', MIN_DATE: 'minDate', MAX_DATE: 'maxDate', BAD_DATE: 'bad