@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
JavaScript
"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