UNPKG

@nimel/directorr-form

Version:
332 lines (316 loc) 13.8 kB
/* (c) Nikita Melnikov - MIT Licensed 2020 - now */ import { observable, computed, makeObservable } from 'mobx'; import { createActionAndEffect, EMPTY_OBJECT, EMPTY_STRING, createPropertyDecoratorFactory, isFunction, callWithPropNotEquallFunc, isLikeAction } from '@nimel/directorr'; export { EMPTY_OBJECT, EMPTY_STRING } from '@nimel/directorr'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } var _a, _b, _c, _d, _e, _f; var actionFormChangeValue = (_a = __read(createActionAndEffect('FORM.CHANGE_VALUE'), 2), _a[0]), effectFormChangeValue = _a[1]; var actionFormFocus = (_b = __read(createActionAndEffect('FORM.FOCUS'), 2), _b[0]), effectFormFocus = _b[1]; var actionFormVisit = (_c = __read(createActionAndEffect('FORM.VISIT'), 2), _c[0]), effectFormVisit = _c[1]; var actionFormChangeStatus = (_d = __read(createActionAndEffect('FORM.CHANGE_STATUS'), 2), _d[0]), effectFormChangeStatus = _d[1]; var actionFormSubmit = (_e = __read(createActionAndEffect('FORM.SUBMIT'), 2), _e[0]), effectFormSubmit = _e[1]; var actionFormReset = (_f = __read(createActionAndEffect('FORM.RESET'), 2), _f[0]), effectFormReset = _f[1]; var FormStore = /** @class */ (function () { function FormStore(_a) { var _b = _a === void 0 ? EMPTY_OBJECT : _a, _c = _b.value, value = _c === void 0 ? EMPTY_STRING : _c, _d = _b.status, status = _d === void 0 ? 0 /* Status.default */ : _d, message = _b.message; var _this = this; this.isChanged = false; this.isVisited = false; this.isFocused = false; this.changeValue = function (value) { return ({ value: value }); }; this.toChangeValue = function (_a) { var value = _a.value; _this.isChanged = true; _this.value = value; }; this.focus = function () { _this.visit(); return { focus: true }; }; this.blur = function () { return ({ focus: false }); }; this.toFocus = function (_a) { var focus = _a.focus; _this.isFocused = focus; }; this.visit = function () { return (_this.isVisited ? null : undefined); }; this.toVisit = function () { _this.isVisited = true; }; this.changeStatusToInvalid = function (message) { return ({ status: 2 /* Status.invalid */, message: message }); }; this.changeStatusToValid = function () { return ({ status: 1 /* Status.valid */ }); }; this.toChangeStatus = function (_a) { var status = _a.status, message = _a.message; _this.status = status; _this.message = message; }; this.submit = function () { }; this.reset = function () { }; this.toReset = function () { _this.value = _this.defaultValue; _this.message = _this.defaultMessage; _this.status = 0 /* Status.default */; }; this.defaultValue = value; this.defaultMessage = message; this.value = value; this.status = status; this.message = message; makeObservable(this); } Object.defineProperty(FormStore.prototype, "isDefault", { get: function () { return this.status === 0 /* Status.default */; }, enumerable: false, configurable: true }); Object.defineProperty(FormStore.prototype, "isValid", { get: function () { return this.status === 1 /* Status.valid */; }, enumerable: false, configurable: true }); Object.defineProperty(FormStore.prototype, "isInvalid", { get: function () { return this.status === 2 /* Status.invalid */; }, enumerable: false, configurable: true }); __decorate([ observable, __metadata("design:type", String) ], FormStore.prototype, "value", void 0); __decorate([ observable, __metadata("design:type", String) ], FormStore.prototype, "message", void 0); __decorate([ observable, __metadata("design:type", Number) ], FormStore.prototype, "status", void 0); __decorate([ observable, __metadata("design:type", Object) ], FormStore.prototype, "isChanged", void 0); __decorate([ observable, __metadata("design:type", Object) ], FormStore.prototype, "isVisited", void 0); __decorate([ observable, __metadata("design:type", Object) ], FormStore.prototype, "isFocused", void 0); __decorate([ computed, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], FormStore.prototype, "isDefault", null); __decorate([ computed, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], FormStore.prototype, "isValid", null); __decorate([ computed, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], FormStore.prototype, "isInvalid", null); __decorate([ actionFormChangeValue, __metadata("design:type", Object) ], FormStore.prototype, "changeValue", void 0); __decorate([ effectFormChangeValue, __metadata("design:type", Object) ], FormStore.prototype, "toChangeValue", void 0); __decorate([ actionFormFocus, __metadata("design:type", Object) ], FormStore.prototype, "focus", void 0); __decorate([ actionFormFocus, __metadata("design:type", Object) ], FormStore.prototype, "blur", void 0); __decorate([ effectFormFocus, __metadata("design:type", Object) ], FormStore.prototype, "toFocus", void 0); __decorate([ actionFormVisit, __metadata("design:type", Object) ], FormStore.prototype, "visit", void 0); __decorate([ effectFormVisit, __metadata("design:type", Object) ], FormStore.prototype, "toVisit", void 0); __decorate([ actionFormChangeStatus, __metadata("design:type", Object) ], FormStore.prototype, "changeStatusToInvalid", void 0); __decorate([ actionFormChangeStatus, __metadata("design:type", Object) ], FormStore.prototype, "changeStatusToValid", void 0); __decorate([ effectFormChangeStatus, __metadata("design:type", Object) ], FormStore.prototype, "toChangeStatus", void 0); __decorate([ actionFormSubmit, __metadata("design:type", Object) ], FormStore.prototype, "submit", void 0); __decorate([ actionFormReset, __metadata("design:type", Object) ], FormStore.prototype, "reset", void 0); __decorate([ effectFormReset, __metadata("design:type", Object) ], FormStore.prototype, "toReset", void 0); return FormStore; }()); var useWithEffects = function (moduleName) { return "".concat(moduleName, ": use only with effect decorator"); }; var callWithWrongSchema = function (moduleName, schema) { return "".concat(moduleName, ": call with arg=").concat(schema, " not like yup - ObjectSchema"); }; var propNotExistInClass = function (moduleName, prop, store) { return "".concat(moduleName, ": formStore in prop=").concat(prop, " not exist in class=").concat(store); }; var propInClassNotLikeFormStore = function (moduleName, prop, formStore) { return "".concat(moduleName, ": formStore in prop=").concat(prop, " not like FormStore=").concat(formStore); }; var DEFAULT_VALIDATE_OPTIONS = { abortEarly: false, strict: true, payloadProp: 'connectStoreProperty', }; function isLikeYUPSchema(schema) { return !!schema.fields; } function createSchemaContext(moduleName, schema, options) { if (options === void 0) { options = {}; } if (!isLikeYUPSchema(schema)) throw new TypeError(callWithWrongSchema(moduleName, schema)); return [schema, __assign(__assign({}, DEFAULT_VALIDATE_OPTIONS), options), Object.keys(schema.fields)]; } var VALUE_PROP_NAME = 'value'; function isLikeFormStore(store) { return !!(VALUE_PROP_NAME in store && store.changeStatusToInvalid && store.changeStatusToValid); } function calcValues(moduleName, fields, store) { var result = {}; for (var i = 0, l = fields.length, prop = void 0, formStore = void 0; i < l; ++i) { prop = fields[i]; formStore = store[prop]; if (!formStore) throw new Error(propNotExistInClass(moduleName, prop, store)); if (!isLikeFormStore(formStore)) throw new TypeError(propInClassNotLikeFormStore(moduleName, prop, formStore)); result[prop] = formStore.value || undefined; } return result; } var MODULE_NAME = 'validate'; function validateSchema(payload, valueFunc, store, _a) { var _b = __read(_a, 3), schema = _b[0], options = _b[1], fields = _b[2]; if (isLikeAction(payload)) throw new Error(useWithEffects(MODULE_NAME)); var resultPayload = payload || EMPTY_OBJECT; var payloadProp = resultPayload[options.payloadProp]; if (!payloadProp) return; var values = calcValues(MODULE_NAME, fields, store); try { schema.validateSyncAt(payloadProp, values, options); store[payloadProp].changeStatusToValid(); } catch (validationError) { store[payloadProp].changeStatusToInvalid(validationError.errors[0]); resultPayload = __assign(__assign({}, resultPayload), { validationError: validationError }); } return valueFunc(resultPayload); } function initializer(initObject, value, property, ctx, validate) { if (validate === void 0) { validate = validateSchema; } if (!isFunction(value)) throw new TypeError(callWithPropNotEquallFunc(MODULE_NAME, property)); return function (payload) { return validate(payload, value, initObject, ctx); }; } var validate = createPropertyDecoratorFactory(MODULE_NAME, initializer, createSchemaContext); var MODULE_NAME$1 = 'validateAll'; function validateSchema$1(payload, valueFunc, store, _a) { var _b = __read(_a, 3), schema = _b[0], options = _b[1], fields = _b[2]; if (isLikeAction(payload)) throw new Error(useWithEffects(MODULE_NAME$1)); var resultPayload = payload || EMPTY_OBJECT; var values = calcValues(MODULE_NAME$1, fields, store); try { schema.validateSync(values, options); fields.forEach(function (prop) { return store[prop].changeStatusToValid(); }); } catch (validationError) { validationError.inner.forEach(function (e) { return store[e.path].changeStatusToInvalid(e.message); }); resultPayload = __assign(__assign({}, resultPayload), { validationError: validationError }); } return valueFunc(resultPayload); } function initializer$1(initObject, value, property, ctx, validate) { if (validate === void 0) { validate = validateSchema$1; } if (!isFunction(value)) throw new Error(callWithPropNotEquallFunc(MODULE_NAME$1, property)); return function (payload) { return validate(payload, value, initObject, ctx); }; } var validateAll = createPropertyDecoratorFactory(MODULE_NAME$1, initializer$1, createSchemaContext); export { FormStore, actionFormChangeStatus, actionFormChangeValue, actionFormFocus, actionFormReset, actionFormSubmit, actionFormVisit, effectFormChangeStatus, effectFormChangeValue, effectFormFocus, effectFormReset, effectFormSubmit, effectFormVisit, validate, validateAll };