UNPKG

@commodo/fields

Version:

Enables defining rich data models by decorating function instances with specified model fields. Additionally, it adds `populate` and `validate` methods, for populating model instances with data, and then validating it, respectively.

191 lines (146 loc) 5.48 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _WithFieldsError = _interopRequireDefault(require("./../WithFieldsError")); var _repropose = require("repropose"); var _fields = require("@commodo/fields"); var _name = require("@commodo/name"); var _withFieldDataTypeValidation = _interopRequireDefault(require("./withFieldDataTypeValidation")); var _createField = _interopRequireDefault(require("./createField")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } const prepareValue = ({ value, instanceOf }) => { let newValue = null; if (value) { if ((0, _fields.hasFields)(value)) { newValue = value; } else { newValue = new instanceOf(); if (typeof newValue.populate === "function") { newValue.populate(value); } else { throw new _WithFieldsError.default(`Cannot populate model "${instanceOf}" - "populate" method missing. Forgot to use "withFields"?`, _WithFieldsError.default.MODEL_POPULATE_MISSING); } } } return newValue; }; const fields = (_ref) => { let { list, instanceOf } = _ref, rest = (0, _objectWithoutProperties2.default)(_ref, ["list", "instanceOf"]); if (!instanceOf) { throw new _WithFieldsError.default(`When defining a "fields" field, "instanceOf" argument must be set.`, _WithFieldsError.default.MODEL_FIELD_INSTANCEOF_NOT_SET); } const field = (0, _createField.default)(_objectSpread(_objectSpread({}, rest), {}, { list, type: "fields" })); (0, _repropose.withProps)(instance => { const { setValue, validate, isDirty, clean } = instance; return { instanceOf, isDirty() { if (isDirty.call(this)) { return true; } if (instance.current === null) { return false; } if (instance.list) { for (let i = 0; i < instance.current.length; i++) { let currentElement = instance.current[i]; if (currentElement.isDirty()) { return true; } } return false; } return (0, _fields.hasFields)(instance.current) && instance.current.isDirty(); }, clean() { clean.call(this); if (instance.current === null) { return this; } if (instance.list) { for (let i = 0; i < instance.current.length; i++) { let currentElement = instance.current[i]; if (currentElement.isDirty()) { currentElement.clean(); } } return this; } if (instance.current.isDirty()) { instance.current.clean(); } return this; }, setValue(value) { if (value === null) { return setValue.call(this, null); } if (this.list) { const preparedValues = []; value.forEach(item => preparedValues.push(prepareValue({ value: item, instanceOf }))); return setValue.call(this, preparedValues); } const preparedValue = prepareValue({ value, instanceOf }); return setValue.call(this, preparedValue); }, async validate() { await validate.call(this); if (this.current === null) { return; } if (this.list) { for (let i = 0; i < this.current.length; i++) { const current = this.current[i]; current && (await current.validate()); } return; } this.current && (await this.current.validate()); } }; })(field); (0, _withFieldDataTypeValidation.default)(value => { if (typeof value === "object") { if ((0, _fields.hasFields)(value)) { // If both received value and instanceOf has a name attached, let's compare by it. if ((0, _name.hasName)(value) && (0, _name.hasName)(instanceOf)) { return (0, _name.getName)(value) === (0, _name.getName)(instanceOf); } return value instanceof instanceOf; } return true; } return false; })(field); return field; }; var _default = fields; exports.default = _default; //# sourceMappingURL=fields.js.map