react-easel
Version:
Widget to dynamically build forms using simple-schema and uniforms
1,564 lines (1,245 loc) • 1.24 MB
JavaScript
(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