mobx-react-form
Version:
Reactive MobX Form State Management
3,571 lines • 145 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("_"), require("mobx"));
else if(typeof define === 'function' && define.amd)
define(["_", "mobx"], factory);
else if(typeof exports === 'object')
exports["MobxReactForm"] = factory(require("_"), require("mobx"));
else
root["MobxReactForm"] = factory(root["_"], root["mobx"]);
})(self, (__WEBPACK_EXTERNAL_MODULE_lodash__, __WEBPACK_EXTERNAL_MODULE_mobx__) => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/Base.ts":
/*!*********************!*\
!*** ./src/Base.ts ***!
\*********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
const OptionsModel_1 = __webpack_require__(/*! ./models/OptionsModel */ "./src/models/OptionsModel.ts");
const ValidatorInterface_1 = __webpack_require__(/*! ./models/ValidatorInterface */ "./src/models/ValidatorInterface.ts");
class Base {
constructor() {
Object.defineProperty(this, "noop", {
enumerable: true,
configurable: true,
writable: true,
value: () => { }
});
Object.defineProperty(this, "state", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "fields", {
enumerable: true,
configurable: true,
writable: true,
value: mobx_1.observable.map({})
});
Object.defineProperty(this, "path", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$submitted", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "$submitting", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$validated", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "$validating", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$clearing", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$resetting", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$touched", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$changed", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "$hooks", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
Object.defineProperty(this, "$handlers", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
Object.defineProperty(this, "execHook", {
enumerable: true,
configurable: true,
writable: true,
value: (name, fallback = {}) => (0, utils_1.$try)(fallback[name], this.$hooks[name], this.noop).apply(this, [this])
});
Object.defineProperty(this, "execHandler", {
enumerable: true,
configurable: true,
writable: true,
value: (name, args, fallback = undefined, hook = null, execHook = true) => [
(0, utils_1.$try)(this.$handlers[name] && this.$handlers[name].apply(this, [this]), fallback, this.noop).apply(this, [...args]),
execHook && this.execHook(hook || name),
]
});
/**
Interceptor
*/
Object.defineProperty(this, "intercept", {
enumerable: true,
configurable: true,
writable: true,
value: (opt) => this.MOBXEvent((typeof opt === 'function')
? { type: "interceptor", call: opt }
: Object.assign({ type: "interceptor" }, opt))
});
/**
Observer
*/
Object.defineProperty(this, "observe", {
enumerable: true,
configurable: true,
writable: true,
value: (opt) => this.MOBXEvent((typeof opt === 'function')
? { type: "observer", call: opt }
: Object.assign({ type: "observer" }, opt))
});
/**
Event Handler: On Clear
*/
Object.defineProperty(this, "onClear", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onClear, args, (e) => {
(0, utils_1.isEvent)(e) && e.preventDefault();
this.clear(true, false);
})
});
/**
Event Handler: On Reset
*/
Object.defineProperty(this, "onReset", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onReset, args, (e) => {
(0, utils_1.isEvent)(e) && e.preventDefault();
this.reset(true, false);
})
});
/**
Event Handler: On Submit
*/
Object.defineProperty(this, "onSubmit", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onSubmit, args, (e, o = {}) => {
(0, utils_1.isEvent)(e) && e.preventDefault();
this.submit(o);
}, null, false)
});
/**
Event Handler: On Add
*/
Object.defineProperty(this, "onAdd", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onAdd, args, (e, val) => {
(0, utils_1.isEvent)(e) && e.preventDefault();
this.add((0, utils_1.isEvent)(val) ? null : val, false);
})
});
/**
Event Handler: On Del
*/
Object.defineProperty(this, "onDel", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onDel, args, (e, path) => {
(0, utils_1.isEvent)(e) && e.preventDefault();
this.del((0, utils_1.isEvent)(path) ? this.path : path, false);
})
});
(0, mobx_1.makeObservable)(this, {
$submitted: mobx_1.observable,
$submitting: mobx_1.observable,
$validated: mobx_1.observable,
$validating: mobx_1.observable,
$clearing: mobx_1.observable,
$resetting: mobx_1.observable,
$touched: mobx_1.observable,
$changed: mobx_1.observable,
$hooks: mobx_1.observable,
$handlers: mobx_1.observable,
changed: mobx_1.computed,
submitted: mobx_1.computed,
submitting: mobx_1.computed,
validated: mobx_1.computed,
validating: mobx_1.computed,
clearing: mobx_1.computed,
resetting: mobx_1.computed,
hasIncrementalKeys: mobx_1.computed,
hasNestedFields: mobx_1.computed,
size: mobx_1.computed,
// initialization
initField: mobx_1.action,
// actions
submit: mobx_1.action,
deepUpdate: mobx_1.action,
set: mobx_1.action,
add: mobx_1.action,
del: mobx_1.action,
});
}
get resetting() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.resetting, true) : this.$resetting;
}
get clearing() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.clearing, true) : this.$clearing;
}
get submitted() {
return (0, mobx_1.toJS)(this.$submitted);
}
get submitting() {
return (0, mobx_1.toJS)(this.$submitting);
}
get validated() {
return (0, mobx_1.toJS)(this.$validated);
}
get validating() {
return (0, mobx_1.toJS)(this.$validating);
}
get hasIncrementalKeys() {
return !!this.fields.size && (0, utils_1.hasIntKeys)(this.fields);
}
get hasNestedFields() {
return this.fields.size !== 0;
}
get size() {
return this.fields.size;
}
get changed() {
return !lodash_1.default.isNil(this.path) && this.hasNestedFields
? (this.reduce((acc, field) => (acc + field.changed), 0) + this.$changed)
: this.$changed;
}
/******************************************************************
Initializer
*/
initFields(initial, update = false) {
const fallback = this.state.options.get(OptionsModel_1.OptionsEnum.fallback);
const $path = (key) => lodash_1.default.trimStart([this.path, key].join("."), ".");
let fields;
fields = (0, parser_1.prepareFieldsData)(initial, this.state.strict, fallback);
fields = (0, parser_1.mergeSchemaDefaults)(fields, this.validator);
// create fields
lodash_1.default.forIn(fields, (field, key) => {
const path = $path(key);
const $f = this.select(path, null, false);
if (lodash_1.default.isNil($f)) {
if (fallback) {
this.initField(key, path, field, update);
}
else {
const structPath = (0, utils_1.pathToStruct)(path);
const struct = this.state.struct();
const found = struct
.filter((s) => s.startsWith(structPath))
.find((s) => s.charAt(structPath.length) === "." ||
s.substring(structPath.length, structPath.length + 2) === "[]" ||
s === structPath);
if (found)
this.initField(key, path, field, update);
}
}
});
}
initField(key, path, data, update = false) {
const initial = this.state.get("current", "props");
const struct = (0, utils_1.pathToStruct)(path);
// try to get props from separated objects
const _try = (prop) => {
const t = lodash_1.default.get(initial[prop], struct);
if ([
FieldProps_1.FieldPropsEnum.input,
FieldProps_1.FieldPropsEnum.output,
FieldProps_1.FieldPropsEnum.converter,
].includes(prop) && typeof t !== "function")
return undefined;
return t;
};
const props = {
$value: lodash_1.default.get(initial[FieldProps_1.SeparatedPropsMode.values], path),
$computed: _try(FieldProps_1.SeparatedPropsMode.computed),
$label: _try(FieldProps_1.SeparatedPropsMode.labels),
$placeholder: _try(FieldProps_1.SeparatedPropsMode.placeholders),
$default: _try(FieldProps_1.SeparatedPropsMode.defaults),
$initial: _try(FieldProps_1.SeparatedPropsMode.initials),
$disabled: _try(FieldProps_1.SeparatedPropsMode.disabled),
$deleted: _try(FieldProps_1.SeparatedPropsMode.deleted),
$type: _try(FieldProps_1.SeparatedPropsMode.types),
$related: _try(FieldProps_1.SeparatedPropsMode.related),
$rules: _try(FieldProps_1.SeparatedPropsMode.rules),
$options: _try(FieldProps_1.SeparatedPropsMode.options),
$bindings: _try(FieldProps_1.SeparatedPropsMode.bindings),
$extra: _try(FieldProps_1.SeparatedPropsMode.extra),
$hooks: _try(FieldProps_1.SeparatedPropsMode.hooks),
$handlers: _try(FieldProps_1.SeparatedPropsMode.handlers),
$validatedWith: _try(FieldProps_1.SeparatedPropsMode.validatedWith),
$validators: _try(FieldProps_1.SeparatedPropsMode.validators),
$observers: _try(FieldProps_1.SeparatedPropsMode.observers),
$interceptors: _try(FieldProps_1.SeparatedPropsMode.interceptors),
$converters: _try(FieldProps_1.SeparatedPropsMode.converters),
$input: _try(FieldProps_1.SeparatedPropsMode.input),
$output: _try(FieldProps_1.SeparatedPropsMode.output),
$autoFocus: _try(FieldProps_1.SeparatedPropsMode.autoFocus),
$ref: _try(FieldProps_1.SeparatedPropsMode.refs),
$nullable: _try(FieldProps_1.SeparatedPropsMode.nullable),
$autoComplete: _try(FieldProps_1.SeparatedPropsMode.autoComplete),
};
const field = this.state.form.makeField({
key,
path,
struct,
data,
props,
update,
state: this.state,
}, data && data[FieldProps_1.FieldPropsEnum.class] || _try(FieldProps_1.SeparatedPropsMode.classes));
this.fields.merge({ [key]: field });
return field;
}
/******************************************************************
Actions
*/
validate(opt, obj) {
const $opt = lodash_1.default.merge(opt, { path: this.path });
return this.state.form.validator.validate($opt, obj);
}
/**
Submit
*/
submit(hooks = {}, { execOnSubmitHook = true, execValidationHooks = true, validate = true } = {}) {
const execOnSubmit = () => this.execHook(FieldProps_1.FieldPropsEnum.onSubmit, hooks);
const submit = execOnSubmitHook ? execOnSubmit() : undefined;
this.$submitting = true;
this.$submitted += 1;
if (!validate || !this.state.options.get(OptionsModel_1.OptionsEnum.validateOnSubmit, this)) {
return Promise
.resolve(submit)
.then((0, mobx_1.action)(() => (this.$submitting = false)))
.catch((0, mobx_1.action)((err) => {
this.$submitting = false;
throw err;
}))
.then(() => this);
}
const exec = (isValid) => isValid
? this.execHook(ValidatorInterface_1.ValidationHooks.onSuccess, hooks)
: this.execHook(ValidatorInterface_1.ValidationHooks.onError, hooks);
return (this.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnSubmit, this),
})
.then(({ isValid }) => {
const handler = execValidationHooks ? exec(isValid) : undefined;
if (isValid)
return Promise.all([submit, handler]);
const $err = this.state.options.get(OptionsModel_1.OptionsEnum.defaultGenericError, this);
const $throw = this.state.options.get(OptionsModel_1.OptionsEnum.submitThrowsError, this);
if ($throw && $err)
this.invalidate();
return Promise.all([submit, handler]);
})
.then((0, mobx_1.action)(() => (this.$submitting = false)))
.catch((0, mobx_1.action)((err) => {
this.$submitting = false;
throw err;
}))
.then(() => this));
}
/**
Check Field Computed Values
*/
check(prop, deep = false) {
(0, utils_1.allowedProps)(FieldProps_1.AllowedFieldPropsTypes.computed, [prop]);
return deep
? (0, utils_1.checkPropOccurrence)({
type: utils_1.props.occurrences[prop],
data: this.deepCheck(utils_1.props.occurrences[prop], prop, this.fields),
})
: this[prop];
}
deepCheck(type, prop, fields) {
const $fields = (0, utils_1.getObservableMapValues)(fields);
return lodash_1.default.transform($fields, (check, field) => {
if (!field.fields.size || !Array.isArray(field.initial)) {
check.push(field[prop]);
}
check.push((0, utils_1.checkPropOccurrence)({
data: this.deepCheck(type, prop, field.fields),
type,
}));
return check;
}, []);
}
/**
Update Field Values recurisvely
OR Create Field if 'undefined'
*/
update(fields) {
if (!lodash_1.default.isPlainObject(fields)) {
throw new Error("The update() method accepts only plain objects.");
}
this.deepUpdate((0, parser_1.prepareFieldsData)({ fields }, this.state.strict), undefined, undefined, fields);
}
deepUpdate(fields, path = "", recursion = true, raw) {
lodash_1.default.each(fields, (field, key) => {
var _a;
const $key = lodash_1.default.has(field, FieldProps_1.FieldPropsEnum.name) ? field.name : key;
const $path = lodash_1.default.trimStart(`${path}.${$key}`, ".");
const strictUpdate = this.state.options.get(OptionsModel_1.OptionsEnum.strictUpdate, this);
const $field = this.select($path, null, strictUpdate);
const $container = this.select(path, null, false) || this.state.form.select(this.path, null, false);
const applyInputConverterOnUpdate = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnUpdate, this);
if (!lodash_1.default.isNil($field) && !lodash_1.default.isUndefined(field)) {
if (Array.isArray($field.values())) {
const n = (_a = lodash_1.default.max(lodash_1.default.map(field.fields, (f, i) => Number(i)))) !== null && _a !== void 0 ? _a : -1;
(0, utils_1.getObservableMapValues)($field.fields).forEach(($f) => {
if (Number($f.name) > n) {
$field.$changed++;
$field.state.form.$changed++;
$field.fields.delete($f.name);
}
});
}
if (field === null || field === void 0 ? void 0 : field.fields) {
const fallback = this.state.options.get(OptionsModel_1.OptionsEnum.fallback);
const x = this.state.struct().findIndex(s => s.startsWith($field.path.replace(/\.\d+\./, '[].') + '[]'));
if (!fallback && $field.fields.size === 0 && x < 0) {
$field.value = (0, parser_1.parseInput)(applyInputConverterOnUpdate ? $field.$input : (val) => val, {
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
separated: lodash_1.default.get(raw, $path),
});
return;
}
}
if (lodash_1.default.isNull(field) || lodash_1.default.isNil(field.fields)) {
$field.value = (0, parser_1.parseInput)(applyInputConverterOnUpdate ? $field.$input : (val) => val, {
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
separated: field,
});
return;
}
}
if (!lodash_1.default.isNil($container) && lodash_1.default.isNil($field)) {
// get full path when using update() with select() - FIX: #179
const $newFieldPath = lodash_1.default.trimStart([this.path, $path].join("."), ".");
// init field into the container field
$container.$changed++;
$container.state.form.$changed++;
$container.initField($key, $newFieldPath, field, true);
}
else if (recursion) {
if (lodash_1.default.has(field, FieldProps_1.FieldPropsEnum.fields) && !lodash_1.default.isNil(field.fields)) {
// handle nested fields if defined
this.deepUpdate(field.fields, $path);
}
else {
// handle nested fields if undefined or null
const $fields = (0, parser_1.pathToFieldsTree)(this.state.struct(), $path);
this.deepUpdate($fields, $path, false);
}
}
});
}
/**
Get Fields Props
*/
get(prop = null, strict = true) {
if (lodash_1.default.isNil(prop)) {
return this.deepGet([...utils_1.props.computed, ...utils_1.props.editable, ...utils_1.props.validation], this.fields, strict);
}
(0, utils_1.allowedProps)(FieldProps_1.AllowedFieldPropsTypes.all, Array.isArray(prop) ? prop : [prop]);
if (lodash_1.default.isString(prop)) {
if ([
FieldProps_1.FieldPropsEnum.hooks,
FieldProps_1.FieldPropsEnum.handlers
].includes(prop)) {
return this[`$${prop}`];
}
if (strict && this.fields.size === 0) {
const retrieveNullifiedEmptyStrings = this.state.options.get(OptionsModel_1.OptionsEnum.retrieveNullifiedEmptyStrings, this);
return (0, parser_1.parseCheckOutput)(this, prop, strict ? retrieveNullifiedEmptyStrings : false);
}
const value = this.deepGet(prop, this.fields, strict);
const removeNullishValuesInArrays = this.state.options.get(OptionsModel_1.OptionsEnum.removeNullishValuesInArrays, this);
return (0, parser_1.parseCheckArray)(this, value, prop, strict ? removeNullishValuesInArrays : false);
}
return this.deepGet(prop, this.fields, strict);
}
/**
Get Fields Props Recursively
*/
deepGet(prop, fields, strict = true) {
return lodash_1.default.transform((0, utils_1.getObservableMapValues)(fields), (obj, field) => {
const $nested = ($fields) => $fields.size !== 0
? this.deepGet(prop, $fields, strict)
: undefined;
Object.assign(obj, {
[field.key]: { fields: $nested(field.fields) },
});
if (lodash_1.default.isString(prop)) {
const opt = this.state.options;
const removeProp = ((opt.get(OptionsModel_1.OptionsEnum.retrieveOnlyDirtyFieldsValues, this) && prop === FieldProps_1.FieldPropsEnum.value && field.isPristine) ||
(opt.get(OptionsModel_1.OptionsEnum.retrieveOnlyEnabledFieldsValues, this) && prop === FieldProps_1.FieldPropsEnum.value && field.disabled) ||
(opt.get(OptionsModel_1.OptionsEnum.retrieveOnlyEnabledFieldsErrors, this) && prop === FieldProps_1.FieldPropsEnum.error && field.disabled && field.isValid && (!field.error || !field.hasError)) ||
(opt.get(OptionsModel_1.OptionsEnum.softDelete, this) && prop === FieldProps_1.FieldPropsEnum.value && field.deleted));
if (field.fields.size === 0) {
delete obj[field.key];
if (removeProp)
return obj;
const retrieveNullifiedEmptyStrings = this.state.options.get(OptionsModel_1.OptionsEnum.retrieveNullifiedEmptyStrings, this);
return Object.assign(obj, {
[field.key]: (0, parser_1.parseCheckOutput)(field, prop, strict ? retrieveNullifiedEmptyStrings : false),
});
}
let value = this.deepGet(prop, field.fields, strict);
if (prop === FieldProps_1.FieldPropsEnum.value)
value = field.$output(value);
delete obj[field.key];
if (removeProp)
return obj;
const removeNullishValuesInArrays = this.state.options.get(OptionsModel_1.OptionsEnum.removeNullishValuesInArrays, this);
return Object.assign(obj, {
[field.key]: (0, parser_1.parseCheckArray)(field, value, prop, strict ? removeNullishValuesInArrays : false),
});
}
lodash_1.default.each(prop, ($prop) => Object.assign(obj[field.key], {
[$prop]: field[$prop],
}));
return obj;
}, {});
}
/**
Set Fields Props
*/
set(prop, data) {
// UPDATE CUSTOM PROP
if (lodash_1.default.isString(prop) && !lodash_1.default.isUndefined(data)) {
(0, utils_1.allowedProps)(FieldProps_1.AllowedFieldPropsTypes.editable, [prop]);
const isPlain = [
FieldProps_1.FieldPropsEnum.hooks,
FieldProps_1.FieldPropsEnum.handlers,
].includes(prop);
const deep = (lodash_1.default.isObject(data) && prop === FieldProps_1.FieldPropsEnum.value) || (lodash_1.default.isPlainObject(data) && !isPlain);
if (deep && this.hasNestedFields)
return this.deepSet(prop, data, "", true);
if (prop === FieldProps_1.FieldPropsEnum.value) {
const applyInputConverterOnSet = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnSet, this);
this.value = (0, parser_1.parseInput)(applyInputConverterOnSet ? this.$input : (val) => val, {
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
separated: data,
});
}
else if (isPlain) {
Object.assign(this[`$${prop}`], data);
}
else {
lodash_1.default.set(this, `$${prop}`, data);
}
return;
}
// NO PROP NAME PROVIDED ("prop" is value)
if (lodash_1.default.isNil(data)) {
if (this.hasNestedFields)
this.deepSet(FieldProps_1.FieldPropsEnum.value, prop, "", true);
else
this.set(FieldProps_1.FieldPropsEnum.value, prop);
}
}
/**
Set Fields Props Recursively
*/
deepSet(prop, data, path = "", recursion = false) {
const err = "You are updating a not existent field:";
const isStrict = this.state.options.get(OptionsModel_1.OptionsEnum.strictSet, this);
if (lodash_1.default.isNil(data)) {
this.each((field) => field.$value = (0, parser_1.defaultValue)({
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
value: field.$value,
nullable: field.$nullable,
type: field.type,
}));
return;
}
lodash_1.default.each(data, ($val, $key) => {
const $path = lodash_1.default.trimStart(`${path}.${$key}`, ".");
// get the field by path joining keys recursively
const field = this.select($path, null, isStrict);
// if no field found when is strict update, throw error
if (isStrict)
(0, utils_1.throwError)($path, field, err);
// update the field/fields if defined
if (!lodash_1.default.isUndefined(field)) {
// update field values or others props
if (!lodash_1.default.isUndefined($val)) {
field.set(prop, $val, recursion);
}
// update values recursively only if field has nested
if (field.fields.size && lodash_1.default.isObject($val)) {
this.deepSet(prop, $val, $path, recursion);
}
}
});
}
/**
Add Field
*/
add(obj, execEvent = true) {
if ((0, utils_1.isArrayOfObjects)(obj)) {
lodash_1.default.each(obj, (values) => this.update({
[(0, utils_1.maxKey)(this.fields)]: values,
}));
this.$changed++;
this.state.form.$changed++;
execEvent && this.execHook(FieldProps_1.FieldPropsEnum.onAdd);
return this;
}
let key;
if (lodash_1.default.has(obj, FieldProps_1.FieldPropsEnum.key))
key = obj.key;
if (lodash_1.default.has(obj, FieldProps_1.FieldPropsEnum.name))
key = obj.name;
if (!key)
key = (0, utils_1.maxKey)(this.fields);
const $path = ($key) => lodash_1.default.trimStart([this.path, $key].join("."), ".");
const tree = (0, parser_1.pathToFieldsTree)(this.state.struct(), this.path, 0, true);
const field = this.initField(key, $path(key), lodash_1.default.merge(tree[0], obj));
const hasValues = lodash_1.default.has(obj, FieldProps_1.FieldPropsEnum.value) || lodash_1.default.has(obj, FieldProps_1.FieldPropsEnum.fields);
if (!hasValues && !this.state.options.get(OptionsModel_1.OptionsEnum.preserveDeletedFieldsValues, this)) {
const fallbackValueOption = this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this);
field.$value = (0, parser_1.defaultValue)({ fallbackValueOption, value: field.$value, nullable: field.$nullable, type: field.type });
field.each((field) => field.$value = (0, parser_1.defaultValue)({
fallbackValueOption,
value: field.$value,
nullable: field.$nullable,
type: field.type
}));
}
this.$changed++;
this.state.form.$changed++;
execEvent && this.execHook(FieldProps_1.FieldPropsEnum.onAdd);
return field;
}
/**
Del Field
*/
del($path = null, execEvent = true) {
const isStrict = this.state.options.get(OptionsModel_1.OptionsEnum.strictDelete, this);
const path = (0, parser_1.parsePath)($path !== null && $path !== void 0 ? $path : this.path);
const fullpath = lodash_1.default.trim([this.path, path].join("."), ".");
const container = this.container($path);
const keys = lodash_1.default.split(path, ".");
const last = lodash_1.default.last(keys);
if (isStrict && !container.fields.has(last)) {
const msg = `Key "${last}" not found when trying to delete field`;
(0, utils_1.throwError)(fullpath, null, msg);
}
container.$changed++;
container.state.form.$changed++;
if (this.state.options.get(OptionsModel_1.OptionsEnum.softDelete, this)) {
return this.select(fullpath).set(FieldProps_1.FieldPropsEnum.deleted, true);
}
container.each((field) => field.debouncedValidation.cancel());
execEvent && this.execHook(FieldProps_1.FieldPropsEnum.onDel);
return container.fields.delete(last);
}
/******************************************************************
Events
*/
/**
MobX Event (observe/intercept)
*/
MOBXEvent({ prop = FieldProps_1.FieldPropsEnum.value, key = null, path = null, call, type }) {
let $prop = key || prop;
(0, utils_1.allowedProps)(FieldProps_1.AllowedFieldPropsTypes.observable, [$prop]);
const $instance = this.select(path || this.path, null, null) || this;
const $call = (change) => call.apply(null, [
{
change,
form: this.state.form,
path: $instance.path || null,
field: $instance.path ? $instance : null,
},
]);
let fn;
let ffn;
if (type === "observer") {
fn = mobx_1.observe;
ffn = (cb) => (0, mobx_1.observe)($instance.fields, cb); // fields
}
if (type === "interceptor") {
$prop = `$${prop}`;
fn = mobx_1.intercept;
ffn = $instance.fields.intercept; // fields
}
const $dkey = $instance.path ? `${$prop}@${$instance.path}` : $prop;
lodash_1.default.merge(this.state.disposers[type], {
[$dkey]: $prop === FieldProps_1.FieldPropsEnum.fields
? ffn.apply((change) => $call(change))
: fn($instance, $prop, (change) => $call(change)),
});
}
/**
Dispose MOBX Events
*/
dispose(opt = null) {
if (this.path && opt)
return this.disposeSingle(opt);
return this.disposeAll();
}
/**
Dispose All Events (observe/intercept)
*/
disposeAll() {
const dispose = (disposer) => disposer.apply();
lodash_1.default.each(this.state.disposers.interceptor, dispose);
lodash_1.default.each(this.state.disposers.observer, dispose);
this.state.disposers = { interceptor: {}, observer: {} };
return null;
}
/**
Dispose Single Event (observe/intercept)
*/
disposeSingle({ type, key = FieldProps_1.FieldPropsEnum.value, path = null }) {
const $path = (0, parser_1.parsePath)(path !== null && path !== void 0 ? path : this.path);
// eslint-disable-next-line
if (type === "interceptor")
key = `$${key}`; // target observables
this.state.disposers[type][`${key}@${$path}`].apply();
delete this.state.disposers[type][`${key}@${$path}`];
}
/******************************************************************
Utils
*/
/**
Fields Selector
*/
select(path, fields = null, isStrict = true) {
const $path = (0, parser_1.parsePath)(path);
const keys = lodash_1.default.split($path, ".");
const head = lodash_1.default.head(keys);
keys.shift();
let $fields = lodash_1.default.isNil(fields)
? this.fields.get(head)
: fields.get(head);
let stop = false;
lodash_1.default.each(keys, ($key) => {
if (stop)
return;
if (lodash_1.default.isNil($fields)) {
$fields = undefined;
stop = true;
}
else {
$fields = $fields.fields.get($key);
}
});
if (isStrict && this.state.options.get(OptionsModel_1.OptionsEnum.strictSelect, this)) {
(0, utils_1.throwError)(path, $fields);
}
return $fields;
}
/**
Get Container
*/
container($path) {
const path = (0, parser_1.parsePath)($path !== null && $path !== void 0 ? $path : this.path);
const cpath = lodash_1.default.trim(path.replace(new RegExp("[^./]+$"), ""), ".");
if (!!this.path && lodash_1.default.isNil($path)) {
return cpath !== ""
? this.state.form.select(cpath, null, false)
: this.state.form;
}
return cpath !== "" ? this.select(cpath, null, false) : this;
}
/**
Has Field
*/
has(path) {
return this.fields.has(path);
}
/**
Map Fields
*/
map(cb) {
return (0, utils_1.getObservableMapValues)(this.fields).map(cb);
}
/**
* Iterates deeply over fields and invokes `iteratee` for each element.
* The iteratee is invoked with three arguments: (value, index|key, depth).
*
* @param {Function} iteratee The function invoked per iteration.
* @param {Array|Object} [fields=form.fields] fields to iterate over.
* @param {number} [depth=1] The recursion depth for internal use.
* @returns {Array} Returns [fields.values()] of input [fields] parameter.
* @example
*
* JSON.stringify(form)
* // => {
* "fields": {
* "state": {
* "fields": {
* "city": {
* "fields": { "places": {
* "fields": {},
* "key": "places", "path": "state.city.places", "$value": "NY Places"
* }
* },
* "key": "city", "path": "state.city", "$value": "New York"
* }
* },
* "key": "state", "path": "state", "$value": "USA"
* }
* }
* }
*
* const data = {};
* form.each(field => data[field.path] = field.value);
* // => {
* "state": "USA",
* "state.city": "New York",
* "state.city.places": "NY Places"
* }
*
*/
each(iteratee, fields = null, depth = 0) {
const $fields = fields || this.fields;
(0, utils_1.getObservableMapValues)($fields).forEach((field, index) => {
iteratee(field, index, depth);
if (field.fields.size !== 0) {
this.each(iteratee, field.fields, depth + 1);
}
});
}
reduce(iteratee, acc) {
return (0, utils_1.getObservableMapValues)(this.fields).reduce(iteratee, acc);
}
/******************************************************************
Helpers
*/
/**
Fields Selector (alias of select)
*/
$(key) {
return this.select(key);
}
/**
Fields Values (recursive with Nested Fields)
*/
values() {
return this.get(FieldProps_1.FieldPropsEnum.value);
}
/**
Fields Errors (recursive with Nested Fields)
*/
errors() {
return this.get(FieldProps_1.FieldPropsEnum.error);
}
/**
Fields Labels (recursive with Nested Fields)
*/
labels() {
return this.get(FieldProps_1.FieldPropsEnum.label);
}
/**
Fields Placeholders (recursive with Nested Fields)
*/
placeholders() {
return this.get(FieldProps_1.FieldPropsEnum.placeholder);
}
/**
Fields Default Values (recursive with Nested Fields)
*/
defaults() {
return this.get(FieldProps_1.FieldPropsEnum.default);
}
/**
Fields Initial Values (recursive with Nested Fields)
*/
initials() {
return this.get(FieldProps_1.FieldPropsEnum.initial);
}
/**
Fields Types (recursive with Nested Fields)
*/
types() {
return this.get(FieldProps_1.FieldPropsEnum.type);
}
}
exports["default"] = Base;
/***/ }),
/***/ "./src/Bindings.ts":
/*!*************************!*\
!*** ./src/Bindings.ts ***!
\*************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
class Bindings {
constructor() {
Object.defineProperty(this, "templates", {
enumerable: true,
configurable: true,
writable: true,
value: {
// default: ({ field, form, props, keys, $try }) => ({
// [keys.id]: $try(props.id, field.id),
// }),
}
});
Object.defineProperty(this, "rewriters", {
enumerable: true,
configurable: true,
writable: true,
value: {
default: {
id: FieldProps_1.FieldPropsEnum.id,
name: FieldProps_1.FieldPropsEnum.name,
type: FieldProps_1.FieldPropsEnum.type,
value: FieldProps_1.FieldPropsEnum.value,
checked: FieldProps_1.FieldPropsEnum.checked,
label: FieldProps_1.FieldPropsEnum.label,
placeholder: FieldProps_1.FieldPropsEnum.placeholder,
disabled: FieldProps_1.FieldPropsEnum.disabled,
autoComplete: FieldProps_1.FieldPropsEnum.autoComplete,
onChange: FieldProps_1.FieldPropsEnum.onChange,
onBlur: FieldProps_1.FieldPropsEnum.onBlur,
onFocus: FieldProps_1.FieldPropsEnum.onFocus,
autoFocus: FieldProps_1.FieldPropsEnum.autoFocus,
inputMode: FieldProps_1.FieldPropsEnum.inputMode,
onKeyUp: FieldProps_1.FieldPropsEnum.onKeyUp,
onKeyDown: FieldProps_1.FieldPropsEnum.onKeyDown,
},
}
});
}
register(bindings) {
lodash_1.default.each(bindings, (val, key) => {
if ((typeof val === 'function'))
lodash_1.default.merge(this.templates, { [key]: val });
if (lodash_1.default.isPlainObject(val))
lodash_1.default.merge(this.rewriters, { [key]: val });
});
return this;
}
load(field, name = FieldProps_1.FieldPropsEnum.default, props) {
const args = ({
keys: lodash_1.default.get(this.rewriters, FieldProps_1.FieldPropsEnum.default),
form: field.state.form,
field,
props,
$try: utils_1.$try,
});
if (lodash_1.default.has(this.templates, FieldProps_1.FieldPropsEnum.default)) {
return lodash_1.default.get(this.templates, name)(args);
}
if (lodash_1.default.has(this.rewriters, name)) {
const $bindings = {};
lodash_1.default.each(lodash_1.default.get(this.rewriters, name), ($v, $k) => lodash_1.default.merge($bindings, { [$v]: (0, utils_1.$try)(props[$k], field[$k]) }));
return $bindings;
}
return lodash_1.default.get(this.templates, name)(args);
}
}
exports["default"] = Bindings;
/***/ }),
/***/ "./src/Field.ts":
/*!**********************!*\
!*** ./src/Field.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const Base_1 = __importDefault(__webpack_require__(/*! ./Base */ "./src/Base.ts"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const parser_1 = __webpack_require__(/*! ./parser */ "./src/parser.ts");
const OptionsModel_1 = __webpack_require__(/*! ./models/OptionsModel */ "./src/models/OptionsModel.ts");
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
const applyFieldPropFunc = (instance, prop) => {
if (typeof prop !== 'function')
return prop;
return prop.apply(instance, [{
field: instance,
form: instance.state.form
}]);
};
const retrieveFieldPropFunc = (prop) => (typeof prop === 'function') ? prop : undefined;
const propGetter = (instance, prop) => (typeof instance[`_${prop}`] === 'function')
? instance[`_${prop}`].apply(instance, [{
form: instance.state.form,
field: instance,
}]) : instance[`$${prop}`];
const setupFieldProps = (instance, props, data) => Object.assign(instance, {
// retrieve functions
_label: retrieveFieldPropFunc(props.$label || (data === null || data === void 0 ? void 0 : data.label)),
_placeholder: retrieveFieldPropFunc(props.$placeholder || (data === null || data === void 0 ? void 0 : data.placeholder)),
_disabled: retrieveFieldPropFunc(props.$disabled || (data === null || data === void 0 ? void 0 : data.disabled)),
_rules: retrieveFieldPropFunc(props.$rules || (data === null || data === void 0 ? void 0 : data.rules)),
_related: retrieveFieldPropFunc(props.$related || (data === null || data === void 0 ? void 0 : data.related)),
_deleted: retrieveFieldPropFunc(props.$deleted || (data === null || data === void 0 ? void 0 : data.deleted)),
_validators: retrieveFieldPropFunc(props.$validators || (data === null || data === void 0 ? void 0 : data.validators)),
_validatedWith: retrieveFieldPropFunc(props.$validatedWith || (data === null || data === void 0 ? void 0 : data.validatedWith)),
_bindings: retrieveFieldPropFunc(props.$bindings || (data === null || data === void 0 ? void 0 : data.bindings)),
_extra: retrieveFieldPropFunc(props.$extra || (data === null || data === void 0 ? void 0 : data.extra)),
_options: retrieveFieldPropFunc(props.$options || (data === null || data === void 0 ? void 0 : data.options)),
_autoFocus: retrieveFieldPropFunc(props.$autoFocus || (data === null || data === void 0 ? void 0 : data.autoFocus)),
_inputMode: retrieveFieldPropFunc(props.$inputMode || (data === null || data === void 0 ? void 0 : data.inputMode)),
// apply functions or value
$label: applyFieldPropFunc(instance, props.$label || (data === null || data === void 0 ? void 0 : data.label) || ""),
$placeholder: applyFieldPropFunc(instance, props.$placeholder || (data === null || data === void 0 ? void 0 : data.placeholder) || ""),
$disabled: applyFieldPropFunc(instance, props.$disabled || (data === null || data === void 0 ? void 0 : data.disabled) || false),
$rules: applyFieldPropFunc(instance, props.$rules || (data === null || data === void 0 ? void 0 : data.rules) || null),
$related: applyFieldPropFunc(instance, props.$related || (data === null || data === void 0 ? void 0 : data.related) || []),
$deleted: applyFieldPropFunc(instance, props.$deleted || (data === null || data === void 0 ? void 0 : data.deleted) || false),
$validatedWith: applyFieldPropFunc(instance, props.$validatedWith || (data === null || data === void 0 ? void 0 : data.validatedWith) || FieldProps_1.FieldPropsEnum.value),
$bindings: applyFieldPropFunc(instance, props.$bindings || (data === null || data === void 0 ? void 0 : data.bindings) || FieldProps_1.FieldPropsEnum.default),
$extra: applyFieldPropFunc(instance, props.$extra || (data === null || data === void 0 ? void 0 : data.extra) || null),
$options: applyFieldPropFunc(instance, props.$options || (data === null || data === void 0 ? void 0 : data.options) || {}),
$autoFocus: applyFieldPropFunc(instance, props.$autoFocus || (data === null || data === void 0 ? void 0 : data.autoFocus) || false),
$inputMode: applyFieldPropFunc(instance, props.$inputMode || (data === null || data === void 0 ? void 0 : data.inputMode) || undefined),
$validators: applyFieldPropFunc(instance, props.$validators || (data === null || data === void 0 ? void 0 : data.validators) || null),
// other props
$hooks: props.$hooks || (data === null || data === void 0 ? void 0 : data.hooks) || {},
$handlers: props.$handlers || (data === null || data === void 0 ? void 0 : data.handlers) || {},
$observers: props.$observers || (data === null || data === void 0 ? void 0 : data.observers) || null,
$interceptors: props.$interceptors || (data === null || data === void 0 ? void 0 : data.interceptors) || null,
$ref: props.$ref || (data === null || data === void 0 ? void 0 : data.ref) || undefined,
$nullable: props.$nullable || (data === null || data === void 0 ? void 0 : data.nullable) || false,
$autoComplete: props.$autoComplete || (data === null || data === void 0 ? void 0 : data.autoComplete) || undefined,
});
const setupDefaultProp = (instance, data, props, update, { isEmptyArray, fallbackValueOption }) => (0, parser_1.parseInput)((val) => val, {
isEmptyArray,
type: instance.type,
unified: update
? (0, parser_1.defaultValue)({
fallbackValueOption,
type: instance.type,
value: instance.value
})
: data === null || data === void 0 ? void 0 : data.default,
separated: props.$default,
fallback: instance.$initial,
});
class Field extends Base_1.default {
constructor({ key, path, struct, data = {}, props = {}, update = false, state, }) {
super();
Object.defineProperty(this, "hasInitialNestedFields", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "incremental", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "id", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "key", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$observers", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$interceptors", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$converter", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "$input", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "$output", {
enumerable: true,
configurable: true,
writable: true,
value: ($) => $
});
Object.defineProperty(this, "_value", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_label", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_placeholder", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_disabled", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_rules", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_related", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_deleted", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_validatedWith", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_validators", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_bindings", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_extra", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_autoFocus", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_inputMode", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$value", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$type", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$label", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$placeholder", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$default", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$initial", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$bindings", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$extra", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$related", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$validatedWith", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$validators", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$rules", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$disabled", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$focused", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$blurred", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$deleted", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$autoFocus", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$inputMode", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "$ref", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "$nullable", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "$autoComplete", {
enumerable: true,
configurable: true,
writable: true,
value: undefined
});
Object.defineProperty(this, "showError", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "errorSync", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "errorAsync", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "validationErrorStack", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "validationFunctionsData", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "validationAsyncData", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "debouncedValidation", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "disposeValidationOnBlur", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "disposeValidationOnChange", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "files", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
/* ------------------------------------------------------------------ */
/* EVENTS HANDLERS */
Object.defineProperty(this, "sync", {
enumerable: true,
configurable: true,
writable: true,
value: (0, mobx_1.action)((e, v = null) => {
const $get = ($) => (0, utils_1.isBool)($, this.value) ? $.target.checked : $.target.value;
// assume "v" or "e" are the values
if (lodash_1.default.isNil(e) || lodash_1.default.isNil(e.target)) {
if (!lodash_1.default.isNil(v) && !lodash_1.default.isNil(v.target)) {
v = $get(v); // eslint-disable-line
}
this.value = (0, utils_1.$try)(e, v);
return;
}
if (!lodash_1.default.isNil(e.target)) {
this.value = $get(e);
return;
}
this.value = e;
})
});
Object.defineProperty(this, "onSync", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.type === "file"
? this.onDrop(...args)
: this.execHandler(FieldProps_1.FieldPropsEnum.onChange, args, this.sync, FieldProps_1.FieldPropsEnum.onSync)
});
Object.defineProperty(this, "onChange", {
enumerable: true,
configurable: true,
writable: true,
value: this.onSync
});
Object.defineProperty(this, "onToggle", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onToggle, args, this.sync)
});
Object.defineProperty(this, "onBlur", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onBlur, args, (0, mobx_1.action)(() => {
this.$focused = false;
this.$blurred = true;
}))
});
Object.defineProperty(this, "onFocus", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onFocus, args, (0, mobx_1.action)(() => {
this.$focused = true;
this.$touched = true;
}))
});
Object.defineProperty(this, "onDrop", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onDrop, args, (0, mobx_1.action)(() => {
const e = args[0];
let files = null;
if ((0, utils_1.isEvent)(e) && (0, utils_1.hasFiles)(e)) {
files = lodash_1.default.map(e.target.files);
}
this.files = [
...lodash_1.default.map(this.files),
...(files || args)
];
}))
});
Object.defineProperty(this, "onKeyDown", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onKeyDown, args)
});
Object.defineProperty(this, "onKeyUp", {
enumerable: true,
configurable: true,
writable: true,
value: (...args) => this.execHandler(FieldProps_1.FieldPropsEnum.onKeyUp, args)
});
(0, mobx_1.makeObservable)(this, {
$options: mobx_1.observable,
$value: mobx_1.observable,
$type: mobx_1.observable,
$label: mobx_1.observable,
$placeholder: mobx_1.observable,
$default: mobx_1.observable,
$initial: mobx_1.observable,
$bindings: mobx_1.observable,
$extra: mobx_1.observable,
$related: mobx_1.observable,
$validatedWith: mobx_1.observable,
$validators: mobx_1.observable,
$rules: mobx_1.observable,
$disabled: mobx_1.observable,
$focused: mobx_1.observable,
$blurred: mobx_1.observable,
$deleted: mobx_1.observable,
showError: mobx_1.observable,
errorSync: mobx_1.observable,
errorAsync: mobx_1.observable,
validationErrorStack: mobx_1.observable,
validationFunctionsData: mobx_1.observable,
validationAsyncData: mobx_1.observable,
files: mobx_1.observable,
autoFocus: mobx_1.computed,
inputMode: mobx_1.computed,
ref: mobx_1.computed,
checkValidationErrors: mobx_1.computed,
checked: mobx_1.computed,
value: mobx_1.computed,
initial: mobx_1.computed,
default: mobx_1.computed,
actionRunning: mobx_1.computed,
type: mobx_1.computed,
label: mobx_1.computed,
placeholder: mobx_1.computed,
extra: mobx_1.computed,
options: mobx_1.computed,
bindings: mobx_1.computed,
related: mobx_1.computed,
disabled: mobx_1.computed,
rules: mobx_1.computed,
validators: mobx_1.computed,
validatedValue: mobx_1.computed,
error: mobx_1.computed,
hasError: mobx_1.computed,
isValid: mobx_1.computed,
isDefault: mobx_1.computed,
isDirty: mobx_1.computed,
isPristine: mobx_1.computed,
isEmpty: mobx_1.computed,
blurred: mobx_1.computed,
touched: mobx_1.computed,
deleted: mobx_1.computed,
setupField: mobx_1.action,
initNestedFields: mobx_1.action,
invalidate: mobx_1.action,
setValidationAsyncData: mobx_1.action,
resetValidation: mobx_1.action,
clear: mobx_1.action,
reset: mobx_1.action,
focus: mobx_1.action,
blur: mobx_1.action,
showErrors: mobx_1.action,
update: mobx_1.action
});
this.state = state;
this.setupField(key, path, struct, data, props, update);
// this.checkValidationPlugins();
this.initNestedFields(data, update);
this.incremental = this.hasIncrementalKeys;
this.debouncedValidation = lodash_1.default.debounce(this.validate, this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceWait, this), this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceOptions, this));
this.observeValidationOnBlur();
this.observeValidationOnChange();
this.initMOBXEvent(FieldProps_1.FieldPropsEnum.observers);
this.initMOBXEvent(FieldProps_1.FieldPropsEnum.interceptors);
// setup hooks & handlers from initialization methods
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$hooks, (_a = this.hooks) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$handlers, (_a = this.handlers) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
this.execHook(FieldProps_1.FieldPropsEnum.onInit);
// handle Field onChange Hook
(0, mobx_1.autorun)(() => this.changed && this.execHook(FieldProps_1.FieldPropsEnum.onChange));
}
/* ------------------------------------------------------------------ */
/* COMPUTED */
get checkValidationErrors() {
var _a;
return ((((_a = this.validationAsyncData) === null || _a === void 0 ? void 0 : _a.valid) === false &&
!lodash_1.default.isEmpty(this.validationAsyncData)) ||
!lodash_1.default.isEmpty(this.validationErrorStack) ||
lodash_1.default.isString(this.errorAsync) ||
lodash_1.default.isString(this.errorSync));
}
set value(newVal) {
if (lodash_1.default.isString(newVal) && this.state.options.get(OptionsModel_1.OptionsEnum.autoTrimValue, this)) {
newVal = newVal.trim();
}
if (this.$value === newVal)
return;
if (this.handleSetNumberValue(newVal))
return;
this.$value = this.$converter(newVal);
this.$changed++;
if (!this.actionRunning) {
this.state.form.$changed++;
}
;
}
handleSetNumberValue(newVal) {
if (!this.state.options.get(OptionsModel_1.OptionsEnum.autoParseNumbers, this))
return false;
if (lodash_1.default.isNumber(this.$initial) || this.type == 'number') {
if (new RegExp("^-?\\d+(,\\d+)*(\\.\\d+([eE]\\d+)?)?$", "g").exec(newVal)) {
this.$value = this.$converter(lodash_1.default.toNumber(newVal));
this.$changed++;
if (!this.actionRunning) {
this.state.form.$changed++;
}
;
return true;
}
}
}
get actionRunning() {
return this.submitting || this.clearing || this.resetting;
}
get checked() {
return this.type === "checkbox" ? this.value : undefined;
}
get value() {
return (typeof this._value === 'function' && !this.hasNestedFields)
? propGetter(this, FieldProps_1.FieldPropsEnum.value)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.value);
}
get initial() {
return this.$initial
? (0, mobx_1.toJS)(this.$initial)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.initial);
}
get default() {
return this.$default
? (0, mobx_1.toJS)(this.$default)
: this.getComputedProp(FieldProps_1.FieldPropsEnum.default);
}
set initial(val) {
this.$initial = val;
}
set default(val) {
this.$default = val;
}
get nullable() {
return propGetter(this, FieldProps_1.FieldPropsEnum.nullable);
}
get autoComplete() {
return propGetter(this, FieldProps_1.FieldPropsEnum.autoComplete);
}
get ref() {
return propGetter(this, FieldProps_1.FieldPropsEnum.ref);
}
get extra() {
return propGetter(this, FieldProps_1.FieldPropsEnum.extra);
}
get autoFocus() {
return propGetter(this, FieldProps_1.FieldPropsEnum.autoFocus);
}
get inputMode() {
return propGetter(this, FieldProps_1.FieldPropsEnum.inputMode);
}
get type() {
return propGetter(this, FieldProps_1.FieldPropsEnum.type);
}
get label() {
return propGetter(this, FieldProps_1.FieldPropsEnum.label);
}
get placeholder() {
return propGetter(this, FieldProps_1.FieldPropsEnum.placeholder);
}
get options() {
return propGetter(this, FieldProps_1.FieldPropsEnum.options);
}
get bindings() {
return propGetter(this, FieldProps_1.FieldPropsEnum.bindings);
}
get related() {
return propGetter(this, FieldProps_1.FieldPropsEnum.related);
}
get disabled() {
return propGetter(this, FieldProps_1.FieldPropsEnum.disabled);
}
get rules() {
return propGetter(this, FieldProps_1.FieldPropsEnum.rules);
}
get validators() {
return propGetter(this, FieldProps_1.FieldPropsEnum.validators);
}
get validatedWith() {
return propGetter(this, FieldProps_1.FieldPropsEnum.validatedWith);
}
get validatedValue() {
return (0, parser_1.parseCheckOutput)(this, this.validatedWith);
}
get error() {
if (this.showError === false)
return null;
return this.errorAsync || this.errorSync || null;
}
get hasError() {
return this.checkValidationErrors || this.check(FieldProps_1.FieldPropsEnum.hasError, true);
}
get isValid() {
return !this.checkValidationErrors && this.check(FieldProps_1.FieldPropsEnum.isValid, true);
}
get isDefault() {
return !lodash_1.default.isNil(this.default) && lodash_1.default.isEqual(this.default, this.value);
}
get isDirty() {
const value = this.changed ? this.value : this.initial;
return !lodash_1.default.isEqual(this.initial, value);
}
get isPristine() {
const value = this.changed ? this.value : this.initial;
return lodash_1.default.isEqual(this.initial, value);
}
get isEmpty() {
if (this.hasNestedFields)
return this.check(FieldProps_1.FieldPropsEnum.isEmpty, true);
if (lodash_1.default.isBoolean(this.value))
return !!this.$value;
if (lodash_1.default.isNumber(this.value))
return false;
if (lodash_1.default.isDate(this.value))
return false;
if (lodash_1.default.isNull(this.value))
return false;
return lodash_1.default.isEmpty(this.value);
}
get focused() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.focused, true) : this.$focused;
}
get blurred() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.blurred, true) : this.$blurred;
}
get touched() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.touched, true) : this.$touched;
}
get deleted() {
return this.hasNestedFields ? this.check(FieldProps_1.FieldPropsEnum.deleted, true) : this.$deleted;
}
setupField($key, $path, $struct, $data, $props, update) {
var _a;
this.key = $key;
this.path = $path;
this.id = (_a = this.state.options.get(OptionsModel_1.OptionsEnum.uniqueId)) === null || _a === void 0 ? void 0 : _a.apply(this, [this]);
const fallbackValueOption = this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this);
const applyInputConverterOnInit = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnInit, this);
const struct = this.state.struct();
const structPath = (0, utils_1.pathToStruct)(this.path);
const isEmptyArray = (0, utils_1.isArrayFromStruct)(struct, structPath);
const { $type, $input, $output, $converter, $converters, $computed } = $props;
if (lodash_1.default.isPlainObject($data)) {
const { type, input, output, converter, converters, computed } = $data;
this.name = lodash_1.default.toString($data.name || $key);
this.$type = $type || type || "text";
this.$converter = (0, utils_1.$try)($converter, $converters, converter, converters, this.$converter);
this.$input = (0, utils_1.$try)($input, input, this.$input);
this.$output = (0, utils_1.$try)($output, output, this.$output);
const value = (0, parser_1.parseInput)(applyInputConverterOnInit ? this.$input : (val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: computed || $data.value,
separated: $computed || $props.$value,
fallback: $props.$initial,
});
this._value = retrieveFieldPropFunc(value);
this.$value = (typeof this._value === 'function')
? applyFieldPropFunc(this, value)
: value;
this.$initial = (0, parser_1.parseInput)((val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $data.initial,
separated: $props.$initial,
fallback: this.$value,
});
this.$default = setupDefaultProp(this, $data, $props, update, {
fallbackValueOption,
isEmptyArray,
});
setupFieldProps(this, $props, $data);
return;
}
/* The field IS the value here */
this.name = lodash_1.default.toString($key);
this.$type = $type || "text";
this.$converter = (0, utils_1.$try)($converter, $converters, this.$converter);
this.$input = (0, utils_1.$try)($input, this.$input);
this.$output = (0, utils_1.$try)($output, this.$output);
const value = (0, parser_1.parseInput)(applyInputConverterOnInit ? this.$input : (val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $computed || $data,
separated: $computed || $props.$value,
});
this._value = retrieveFieldPropFunc(value);
this.$value = (typeof this._value === 'function')
? applyFieldPropFunc(this, value)
: value;
this.$initial = (0, parser_1.parseInput)((val) => val, {
fallbackValueOption,
isEmptyArray,
type: this.type,
unified: $data,
separated: $props.$initial,
fallback: this.$value,
});
this.$default = setupDefaultProp(this, $data, $props, update, {
fallbackValueOption,
isEmptyArray,
});
setupFieldProps(this, $props, $data);
}
getComputedProp(key) {
if (this.incremental || this.hasNestedFields) {
return (key === FieldProps_1.FieldPropsEnum.value)
? this.get(key, false)
: (0, mobx_1.untracked)(() => this.get(key, false));
}
// @ts-ignore
const val = this[`$${key}`];
if (Array.isArray(val) || (0, mobx_1.isObservableArray)(val)) {
return [].slice.call(val);
}
return (0, mobx_1.toJS)(val);
}
// checkValidationPlugins(): void {
// const { drivers } = this.state.form.validator;
// const form = this.state.form.name ? `${this.state.form.name}/` : "";
// if (_.isNil(drivers.dvr) && !_.isNil(this.rules)) {
// throw new Error(
// `The DVR validation rules are defined but no DVR plugin provided. Field: "${
// form + this.path
// }".`
// );
// }
// if (_.isNil(drivers.vjf) && !_.isNil(this.validators)) {
// throw new Error(
// `The VJF validators functions are defined but no VJF plugin provided. Field: "${
// form + this.path
// }".`
// );
// }
// }
initNestedFields(field, update) {
const fields = lodash_1.default.isNil(field) ? null : field.fields;
if (Array.isArray(fields) && !lodash_1.default.isEmpty(fields)) {
this.hasInitialNestedFields = true;
}
this.initFields({ fields }, update);
if (!update && Array.isArray(fields) && lodash_1.default.isEmpty(fields)) {
if (Array.isArray(this.value) && !lodash_1.default.isEmpty(this.value)) {
this.hasInitialNestedFields = true;
this.initFields({ fields, values: this.value }, update);
}
}
}
invalidate(message, deep = true, async = false) {
if (async === true) {
this.errorAsync = message;
this.showErrors(true, deep);
return;
}
if (Array.isArray(message)) {
this.validationErrorStack = message;
this.showErrors(true, deep);
return;
}
this.validationErrorStack.unshift(message);
this.showErrors(true, deep);
}
setValidationAsyncData(valid = false, message = "") {
this.validationAsyncData = { valid, message };
}
resetValidation(deep = false) {
this.showError = false;
this.errorSync = null;
this.errorAsync = null;
this.validationAsyncData = undefined;
this.validationFunctionsData = [];
this.validationErrorStack = [];
Promise.resolve().then((0, mobx_1.action)(() => {
this.$resetting = false;
this.$clearing = false;
}));
deep && this.each((field) => field.resetValidation(deep));
}
clear(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onClear);
this.$clearing = true;
this.$touched = false;
this.$blurred = false;
this.$changed = 0;
this.files = undefined;
this.$value = (0, parser_1.defaultValue)({
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue),
value: this.$value,
nullable: this.$nullable,
type: this.type,
});
deep && this.each((field) => field.clear(deep));
this.state.options.get(OptionsModel_1.OptionsEnum.validateOnClear, this)
? this.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnClear, this),
}) : this.resetValidation(deep);
}
reset(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onReset);
this.$resetting = true;
this.$touched = false;
this.$blurred = false;
this.$changed = 0;
this.files = undefined;
const useDefaultValue = this.$default !== this.$initial;
if (useDefaultValue)
this.value = this.$default;
if (!useDefaultValue)
this.value = this.$initial;
deep && this.each((field) => field.reset(deep));
this.state.options.get(OptionsModel_1.OptionsEnum.validateOnReset, this)
? this.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnReset, this),
}) : this.resetValidation(deep);
}
focus() {
if (this.ref && !this.focused)
this.ref.focus();
this.$focused = true;
this.$touched = true;
}
blur() {
if (this.ref && this.focused)
this.ref.blur();
this.$focused = false;
this.$blurred = true;
}
trim() {
if (!lodash_1.default.isString(this.value))
return;
this.$value = this.value.trim();
}
showErrors(show = true, deep = true) {
var _a, _b;
this.showError = show;
this.errorSync = lodash_1.default.head(this.validationErrorStack) || null;
this.errorAsync = (((_a = this.validationAsyncData) === null || _a === void 0 ? void 0 : _a.valid) === false) ? (_b = this.validationAsyncData) === null || _b === void 0 ? void 0 : _b.message : null;
deep && this.each((field) => field.showErrors(show, deep));
}
observeValidationOnBlur() {
const opt = this.state.options;
if (opt.get(OptionsModel_1.OptionsEnum.validateOnBlur, this)) {
this.disposeValidationOnBlur = (0, mobx_1.observe)(this, "$focused", (change) => change.newValue === false &&
this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnBlur, this),
}));
}
}
observeValidationOnChange() {
const opt = this.state.options;
if (opt.get(OptionsModel_1.OptionsEnum.validateOnChange, this)) {
this.disposeValidationOnChange = (0, mobx_1.observe)(this, "$value", () => !this.actionRunning && this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnChange, this),
}));
}
else if (opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterInitialBlur, this) ||
opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterSubmit, this)) {
this.disposeValidationOnChange = (0, mobx_1.observe)(this, "$value", () => !this.actionRunning && ((opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterInitialBlur, this) && this.blurred)
|| (opt.get(OptionsModel_1.OptionsEnum.validateOnChangeAfterSubmit, this) && this.state.form.submitted))
&& this.debouncedValidation({
showErrors: opt.get(OptionsModel_1.OptionsEnum.showErrorsOnChange, this),
}));
}
}
initMOBXEvent(type) {
if (!Array.isArray(this[`$${type}`]))
return;
let fn;
if (type === FieldProps_1.FieldPropsEnum.observers)
fn = this.observe;
if (type === FieldProps_1.FieldPropsEnum.interceptors)
fn = this.intercept;
this[`$${type}`].map((obj) => fn(lodash_1.default.omit(obj, FieldProps_1.FieldPropsEnum.path)));
}
bind(props = {}) {
return Object.assign(Object.assign({}, this.state.bindings.load(this, this.bindings, props)), { ref: ($ref) => (this.$ref = $ref) });
}
update(fields) {
if (!lodash_1.default.isPlainObject(fields)) {
throw new Error("The update() method accepts only plain objects.");
}
const fallback = this.state.options.get(OptionsModel_1.OptionsEnum.fallback, this);
const applyInputConverterOnUpdate = this.state.options.get(OptionsModel_1.OptionsEnum.applyInputConverterOnUpdate, this);
const x = this.state.struct().findIndex(s => s.startsWith(this.path.replace(/\.\d+\./, '[].') + '[]'));
if (!fallback && this.fields.size === 0 && x < 0) {
this.value = (0, parser_1.parseInput)(applyInputConverterOnUpdate ? this.$input : (val) => val, {
fallbackValueOption: this.state.options.get(OptionsModel_1.OptionsEnum.fallbackValue, this),
separated: fields,
});
return;
}
super.update(fields);
}
}
exports["default"] = Field;
/***/ }),
/***/ "./src/Form.ts":
/*!*********************!*\
!*** ./src/Form.ts ***!
\*********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const Base_1 = __importDefault(__webpack_require__(/*! ./Base */ "./src/Base.ts"));
const Validator_1 = __importDefault(__webpack_require__(/*! ./Validator */ "./src/Validator.ts"));
const State_1 = __importDefault(__webpack_require__(/*! ./State */ "./src/State.ts"));
const Field_1 = __importDefault(__webpack_require__(/*! ./Field */ "./src/Field.ts"));
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
const OptionsModel_1 = __webpack_require__(/*! ./models/OptionsModel */ "./src/models/OptionsModel.ts");
class Form extends Base_1.default {
constructor(setup = {}, { name = "", options = {}, plugins = {}, bindings = {}, hooks = {}, handlers = {}, } = {}) {
super();
Object.defineProperty(this, "name", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "path", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "validator", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "debouncedValidation", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
(0, mobx_1.makeObservable)(this, {
fields: mobx_1.observable,
validatedValues: mobx_1.computed,
error: mobx_1.computed,
hasError: mobx_1.computed,
isValid: mobx_1.computed,
isPristine: mobx_1.computed,
isDirty: mobx_1.computed,
isDefault: mobx_1.computed,
isEmpty: mobx_1.computed,
focused: mobx_1.computed,
touched: mobx_1.computed,
disabled: mobx_1.computed,
// init: action,
invalidate: mobx_1.action,
clear: mobx_1.action,
reset: mobx_1.action,
resetValidation: mobx_1.action,
});
this.name = name;
(0, mobx_1.runInAction)(() => (this.$hooks = hooks));
(0, mobx_1.runInAction)(() => (this.$handlers = handlers));
// load data from initializers methods
const initial = lodash_1.default.each({
setup,
options,
plugins,
bindings,
}, (val, key) => (typeof this[key] === 'function')
? lodash_1.default.merge(val, this[key].apply(this, [this]))
: val);
// setup hooks & handlers from initialization methods
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$hooks, (_a = this.hooks) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
(0, mobx_1.runInAction)(() => { var _a; return Object.assign(this.$handlers, (_a = this.handlers) === null || _a === void 0 ? void 0 : _a.apply(this, [this])); });
this.state = new State_1.default({
form: this,
initial: initial.setup,
options: initial.options,
bindings: initial.bindings,
});
this.validator = new Validator_1.default({
form: this,
plugins: initial.plugins,
});
this.initFields(initial.setup);
this.debouncedValidation = lodash_1.default.debounce(this.validate, this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceWait), this.state.options.get(OptionsModel_1.OptionsEnum.validationDebounceOptions));
// execute validation on form initialization
this.state.options.get(OptionsModel_1.OptionsEnum.validateOnInit)
&& this.validator.validate({
showErrors: this.state.options.get(OptionsModel_1.OptionsEnum.showErrorsOnInit),
});
this.execHook(FieldProps_1.FieldPropsEnum.onInit);
// handle Form onChange Hook
(0, mobx_1.autorun)(() => this.$changed && this.execHook(FieldProps_1.FieldPropsEnum.onChange));
}
/* ------------------------------------------------------------------ */
/* COMPUTED */
get validatedValues() {
const data = {};
this.each(($field) => (data[$field.path] = $field.validatedValue));
return data;
}
get error() {
return this.validator.error;
}
get hasError() {
return !!this.validator.error || this.check(FieldProps_1.FieldPropsEnum.hasError, true);
}
get isValid() {
return !this.validator.error && this.check(FieldProps_1.FieldPropsEnum.isValid, true);
}
get isPristine() {
return this.check(FieldProps_1.FieldPropsEnum.isPristine, true);
}
get isDirty() {
return this.check(FieldProps_1.FieldPropsEnum.isDirty, true);
}
get isDefault() {
return this.check(FieldProps_1.FieldPropsEnum.isDefault, true);
}
get isEmpty() {
return this.check(FieldProps_1.FieldPropsEnum.isEmpty, true);
}
get focused() {
return this.check(FieldProps_1.FieldPropsEnum.focused, true);
}
get touched() {
return this.check(FieldProps_1.FieldPropsEnum.touched, true);
}
get disabled() {
return this.check(FieldProps_1.FieldPropsEnum.disabled, true);
}
makeField(data, FieldClass = Field_1.default) {
return new FieldClass(data);
}
/** DEPRECATED
Init Form Fields and Nested Fields
init($fields: any = null): void {
_.set(this, "fields", observable.map({}));
this.state.initial.props.values = $fields; // eslint-disable-line
this.state.current.props.values = $fields; // eslint-disable-line
this.initFields({
fields: $fields || this.state.struct(),
});
}
*/
invalidate(message = null, deep = true) {
this.debouncedValidation.cancel();
this.validator.error = message || this.state.options.get(OptionsModel_1.OptionsEnum.defaultGenericError) || true;
deep && this.each((field) => field.debouncedValidation.cancel());
}
showErrors(show = true) {
this.each((field) => field.showErrors(show));
}
resetValidation(deep = true) {
this.validator.error = null;
deep && this.each((field) => field.resetValidation(deep));
}
/**
Clear Form Fields
*/
clear(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onClear);
this.$touched = false;
this.$changed = 0;
deep && this.each((field) => field.clear(deep));
}
/**
Reset Form Fields
*/
reset(deep = true, execHook = true) {
execHook && this.execHook(FieldProps_1.FieldPropsEnum.onReset);
this.$touched = false;
this.$changed = 0;
deep && this.each((field) => field.reset(deep));
}
}
exports["default"] = Form;
/***/ }),
/***/ "./src/Options.ts":
/*!************************!*\
!*** ./src/Options.ts ***!
\************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
class Options {
constructor() {
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: {
uniqueId: utils_1.uniqueId,
fallback: true,
fallbackValue: "",
defaultGenericError: null,
submitThrowsError: true,
showErrorsOnInit: false,
showErrorsOnSubmit: true,
showErrorsOnBlur: true,
showErrorsOnChange: true,
showErrorsOnClear: false,
showErrorsOnReset: true,
validateOnInit: true,
validateOnSubmit: true,
validateOnBlur: true,
validateOnChange: false,
validateOnChangeAfterInitialBlur: false,
validateOnChangeAfterSubmit: false,
validateOnClear: false,
validateOnReset: false,
validateDisabledFields: false,
validateDeletedFields: false,
validatePristineFields: true,
strictSet: false,
strictUpdate: false,
strictDelete: true,
strictSelect: true,
softDelete: false,
retrieveOnlyDirtyFieldsValues: false,
retrieveOnlyEnabledFieldsValues: false,
retrieveOnlyEnabledFieldsErrors: false,
retrieveNullifiedEmptyStrings: false,
autoTrimValue: false,
autoParseNumbers: false,
removeNullishValuesInArrays: false,
preserveDeletedFieldsValues: false,
validationDebounceWait: 250,
validationDebounceOptions: {
leading: false,
trailing: true,
},
stopValidationOnError: false,
validationPluginsOrder: undefined,
resetValidationBeforeValidate: true,
validateTrimmedValue: false,
applyInputConverterOnInit: true,
applyInputConverterOnSet: true,
applyInputConverterOnUpdate: true,
}
});
(0, mobx_1.makeObservable)(this, {
options: mobx_1.observable,
set: mobx_1.action,
});
}
get(key, field = null) {
// handle field option
if (lodash_1.default.has(field, "path")) {
if (lodash_1.default.has(field.$options, key)) {
return field.$options[key];
}
}
// fallback on global form options
if (key)
return lodash_1.default.get(this.options, key);
return (0, mobx_1.toJS)(this.options);
}
set(options) {
if (mobx_1.set) {
(0, mobx_1.set)(this.options, options);
}
else {
(0, mobx_1.extendObservable)(this.options, options);
}
}
}
exports["default"] = Options;
/***/ }),
/***/ "./src/State.ts":
/*!**********************!*\
!*** ./src/State.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const Options_1 = __importDefault(__webpack_require__(/*! ./Options */ "./src/Options.ts"));
const Bindings_1 = __importDefault(__webpack_require__(/*! ./Bindings */ "./src/Bindings.ts"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const StateInterface_1 = __webpack_require__(/*! ./models/StateInterface */ "./src/models/StateInterface.ts");
const OptionsModel_1 = __webpack_require__(/*! ./models/OptionsModel */ "./src/models/OptionsModel.ts");
class State {
constructor({ form, initial, options, bindings }) {
Object.defineProperty(this, "mode", {
enumerable: true,
configurable: true,
writable: true,
value: StateInterface_1.RuntimeMode.mixed
});
Object.defineProperty(this, "strict", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "form", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "options", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "bindings", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$extra", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "$struct", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "disposers", {
enumerable: true,
configurable: true,
writable: true,
value: {
interceptor: {},
observer: {},
}
});
Object.defineProperty(this, "initial", {
enumerable: true,
configurable: true,
writable: true,
value: {
props: {},
fields: {},
}
});
Object.defineProperty(this, "current", {
enumerable: true,
configurable: true,
writable: true,
value: {
props: {},
fields: {},
}
});
this.set("form", form);
this.initProps(initial);
this.options = new Options_1.default();
this.options.set(options);
this.bindings = new Bindings_1.default();
this.bindings.register(bindings);
this.observeOptions();
}
initProps(initial = {}) {
const initialProps = lodash_1.default.pick(initial, [
...utils_1.props.editable,
...utils_1.props.separated,
...utils_1.props.validation,
...utils_1.props.functions,
...utils_1.props.handlers,
]);
this.set("initial", "props", initialProps);
const $unified = (0, utils_1.hasUnifiedProps)(initial);
const $separated = (0, utils_1.hasSeparatedProps)(initial);
if (($separated || (0, utils_1.isArrayOfStrings)(initial.fields)) && !$unified) {
const struct = (0, utils_1.$try)(initial.struct, initial.fields);
this.struct(struct);
this.strict = true;
this.mode = StateInterface_1.RuntimeMode.separated;
return;
}
this.struct(initial.struct);
this.mode = StateInterface_1.RuntimeMode.unified;
}
/**
Get/Set Fields Structure
*/
struct(data = null) {
if (data)
this.$struct = data;
return this.$struct;
}
/**
Get Props/Fields
*/
get(type, subtype) {
return this[type][subtype];
}
/**
Set Props/Fields
*/
set(type, subtype, state = null) {
if (type === "form") {
// subtype is the form here
this.form = subtype;
}
if (type === "initial") {
Object.assign(this.initial[subtype], state);
Object.assign(this.current[subtype], state);
}
if (type === "current") {
Object.assign(this.current[subtype], state);
}
}
extra(data = null) {
if (lodash_1.default.isString(data))
return lodash_1.default.get(this.$extra, data);
if (data === null)
return this.$extra;
this.$extra = data;
return null;
}
observeOptions() {
// Fix Issue #201
(0, mobx_1.observe)(this.options.options, (0, utils_1.checkObserve)([
{
// start observing fields validateOnChange
type: "update",
key: OptionsModel_1.OptionsEnum.validateOnChange,
to: true,
exec: () => this.form.each((field) => field.observeValidationOnChange()),
},
{
// stop observing fields validateOnChange
type: "update",
key: OptionsModel_1.OptionsEnum.validateOnChange,
to: false,
exec: () => this.form.each((field) => field.disposeValidationOnChange()),
},
{
// start observing fields validateOnBlur
type: "update",
key: OptionsModel_1.OptionsEnum.validateOnBlur,
to: true,
exec: () => this.form.each((field) => field.observeValidationOnBlur()),
},
{
// stop observing fields validateOnBlur
type: "update",
key: OptionsModel_1.OptionsEnum.validateOnBlur,
to: false,
exec: () => this.form.each((field) => field.disposeValidationOnBlur()),
},
]));
}
}
exports["default"] = State;
/***/ }),
/***/ "./src/Validator.ts":
/*!**************************!*\
!*** ./src/Validator.ts ***!
\**************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const OptionsModel_1 = __webpack_require__(/*! ./models/OptionsModel */ "./src/models/OptionsModel.ts");
class Validator {
constructor(obj) {
Object.defineProperty(this, "promises", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "form", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "drivers", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
Object.defineProperty(this, "plugins", {
enumerable: true,
configurable: true,
writable: true,
value: {
vjf: undefined,
dvr: undefined,
svk: undefined,
yup: undefined,
zod: undefined,
joi: undefined,
}
});
Object.defineProperty(this, "error", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
(0, mobx_1.makeObservable)(this, {
error: mobx_1.observable,
validate: mobx_1.action,
validateField: mobx_1.action,
});
this.form = obj.form;
Object.assign(this.plugins, obj.plugins);
this.initDrivers();
}
initDrivers() {
lodash_1.default.map(this.plugins, (plugin, key) => (this.drivers[key] = (plugin && plugin.class) &&
new plugin.class({
config: plugin.config,
state: this.form.state,
promises: this.promises,
})));
}
validate(opt, obj) {
const path = (0, utils_1.$try)(opt === null || opt === void 0 ? void 0 : opt.path, opt);
const instance = (0, utils_1.$try)(opt === null || opt === void 0 ? void 0 : opt.field, this.form.select(path, null, false), this.form);
const related = (0, utils_1.$try)(opt === null || opt === void 0 ? void 0 : opt.related, obj === null || obj === void 0 ? void 0 : obj.related, true);
const showErrors = (0, utils_1.$try)(opt === null || opt === void 0 ? void 0 : opt.showErrors, obj === null || obj === void 0 ? void 0 : obj.showErrors, false);
instance.$validating = true;
instance.$validated += 1;
this.error = null;
return new Promise((resolve) => {
// validate instance (form or filed)
if (instance.path || lodash_1.default.isString(path)) {
this.validateField({
field: instance,
showErrors,
related,
path,
});
}
// validate nested fields
instance.each((field) => this.validateField({
path: field.path,
field: field,
showErrors,
related,
}));
// wait all promises
resolve(Promise.all(this.promises));
})
.then((0, mobx_1.action)(() => {
instance.$validating = false;
instance.$clearing = false;
instance.$resetting = false;
}))
.catch((0, mobx_1.action)((err) => {
instance.$validating = false;
instance.$clearing = false;
instance.$resetting = false;
throw err;
}))
.then(() => instance);
}
validateField({ showErrors = false, related = false, field = null, path, }) {
const instance = field || this.form.select(path);
const { options } = this.form.state;
// check if the field is a valid instance
if (!instance.path)
throw new Error("Validation Error: Invalid Field Instance");
// do not validate soft deleted fields
if (instance.deleted && !options.get(OptionsModel_1.OptionsEnum.validateDeletedFields, instance))
return;
// do not validate disabled fields
if (instance.disabled && !options.get(OptionsModel_1.OptionsEnum.validateDisabledFields, instance))
return;
// do not validate pristine fields
if (instance.isPristine && !options.get(OptionsModel_1.OptionsEnum.validatePristineFields, instance))
return;
// reset validation before validate
if (options.get(OptionsModel_1.OptionsEnum.resetValidationBeforeValidate, instance))
instance.resetValidation();
// trim string value before validation
if (options.get(OptionsModel_1.OptionsEnum.validateTrimmedValue, instance))
instance.trim();
// get stop on error
const stopOnError = options.get(OptionsModel_1.OptionsEnum.stopValidationOnError, instance);
// get validation plugin order
const validationPluginOrder = options.get(OptionsModel_1.OptionsEnum.validationPluginsOrder, instance);
const drivers = validationPluginOrder
? validationPluginOrder.map((n) => this.drivers[n])
: this.drivers;
// validate with all enabled drivers
lodash_1.default.each(drivers, (driver) => {
driver && driver.validate(instance);
if (stopOnError && instance.hasError)
return;
});
// send error to the view
instance.showErrors(showErrors, false);
// related validation
if (related)
this.validateRelatedFields(instance, showErrors);
}
/**
Validate 'related' fields if specified
and related validation allowed (recursive)
*/
validateRelatedFields(field, showErrors) {
if (!field.related || !field.related.length)
return;
field.related.map((path) => this.validateField({
related: false,
showErrors,
path,
}));
}
}
exports["default"] = Validator;
/***/ }),
/***/ "./src/index.ts":
/*!**********************!*\
!*** ./src/index.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Field = exports.Form = void 0;
const Form_1 = __importDefault(__webpack_require__(/*! ./Form */ "./src/Form.ts"));
exports.Form = Form_1.default;
const Field_1 = __importDefault(__webpack_require__(/*! ./Field */ "./src/Field.ts"));
exports.Field = Field_1.default;
exports["default"] = Form_1.default;
/***/ }),
/***/ "./src/models/FieldProps.ts":
/*!**********************************!*\
!*** ./src/models/FieldProps.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SeparatedPropsMode = exports.FieldPropsOccurrence = exports.AllowedFieldPropsTypes = exports.FieldPropsEnum = void 0;
var FieldPropsEnum;
(function (FieldPropsEnum) {
FieldPropsEnum["key"] = "key";
FieldPropsEnum["id"] = "id";
FieldPropsEnum["path"] = "path";
FieldPropsEnum["name"] = "name";
FieldPropsEnum["fields"] = "fields";
FieldPropsEnum["ref"] = "ref";
FieldPropsEnum["type"] = "type";
FieldPropsEnum["computed"] = "computed";
FieldPropsEnum["value"] = "value";
FieldPropsEnum["initial"] = "initial";
FieldPropsEnum["default"] = "default";
FieldPropsEnum["checked"] = "checked";
FieldPropsEnum["label"] = "label";
FieldPropsEnum["placeholder"] = "placeholder";
FieldPropsEnum["error"] = "error";
FieldPropsEnum["validatedWith"] = "validatedWith";
FieldPropsEnum["validators"] = "validators";
FieldPropsEnum["rules"] = "rules";
FieldPropsEnum["related"] = "related";
FieldPropsEnum["options"] = "options";
FieldPropsEnum["extra"] = "extra";
FieldPropsEnum["bindings"] = "bindings";
FieldPropsEnum["hooks"] = "hooks";
FieldPropsEnum["handlers"] = "handlers";
FieldPropsEnum["converter"] = "converter";
FieldPropsEnum["input"] = "input";
FieldPropsEnum["output"] = "output";
FieldPropsEnum["interceptors"] = "interceptors";
FieldPropsEnum["observers"] = "observers";
// computed
FieldPropsEnum["disabled"] = "disabled";
FieldPropsEnum["deleted"] = "deleted";
FieldPropsEnum["blurred"] = "blurred";
FieldPropsEnum["validating"] = "validating";
FieldPropsEnum["submitting"] = "submitting";
FieldPropsEnum["clearing"] = "clearing";
FieldPropsEnum["resetting"] = "resetting";
FieldPropsEnum["changed"] = "changed";
FieldPropsEnum["touched"] = "touched";
FieldPropsEnum["focused"] = "focused";
FieldPropsEnum["isEmpty"] = "isEmpty";
FieldPropsEnum["isDefault"] = "isDefault";
FieldPropsEnum["isPristine"] = "isPristine";
FieldPropsEnum["isDirty"] = "isDirty";
FieldPropsEnum["isValid"] = "isValid";
FieldPropsEnum["hasError"] = "hasError";
// handlers
FieldPropsEnum["onInit"] = "onInit";
FieldPropsEnum["onSync"] = "onSync";
FieldPropsEnum["onChange"] = "onChange";
FieldPropsEnum["onBlur"] = "onBlur";
FieldPropsEnum["onFocus"] = "onFocus";
FieldPropsEnum["onToggle"] = "onToggle";
FieldPropsEnum["onDrop"] = "onDrop";
FieldPropsEnum["onSubmit"] = "onSubmit";
FieldPropsEnum["onReset"] = "onReset";
FieldPropsEnum["onClear"] = "onClear";
FieldPropsEnum["onAdd"] = "onAdd";
FieldPropsEnum["onDel"] = "onDel";
FieldPropsEnum["autoFocus"] = "autoFocus";
FieldPropsEnum["inputMode"] = "inputMode";
FieldPropsEnum["onKeyDown"] = "onKeyDown";
FieldPropsEnum["onKeyUp"] = "onKeyUp";
FieldPropsEnum["class"] = "class";
FieldPropsEnum["nullable"] = "nullable";
FieldPropsEnum["autoComplete"] = "autoComplete";
})(FieldPropsEnum = exports.FieldPropsEnum || (exports.FieldPropsEnum = {}));
var AllowedFieldPropsTypes;
(function (AllowedFieldPropsTypes) {
AllowedFieldPropsTypes["computed"] = "computed";
AllowedFieldPropsTypes["observable"] = "observable";
AllowedFieldPropsTypes["editable"] = "editable";
AllowedFieldPropsTypes["all"] = "all";
})(AllowedFieldPropsTypes = exports.AllowedFieldPropsTypes || (exports.AllowedFieldPropsTypes = {}));
var FieldPropsOccurrence;
(function (FieldPropsOccurrence) {
FieldPropsOccurrence["some"] = "some";
FieldPropsOccurrence["every"] = "every";
})(FieldPropsOccurrence = exports.FieldPropsOccurrence || (exports.FieldPropsOccurrence = {}));
var SeparatedPropsMode;
(function (SeparatedPropsMode) {
SeparatedPropsMode["computed"] = "computed";
SeparatedPropsMode["values"] = "values";
SeparatedPropsMode["labels"] = "labels";
SeparatedPropsMode["placeholders"] = "placeholders";
SeparatedPropsMode["defaults"] = "defaults";
SeparatedPropsMode["initials"] = "initials";
SeparatedPropsMode["disabled"] = "disabled";
SeparatedPropsMode["deleted"] = "deleted";
SeparatedPropsMode["types"] = "types";
SeparatedPropsMode["related"] = "related";
SeparatedPropsMode["rules"] = "rules";
SeparatedPropsMode["options"] = "options";
SeparatedPropsMode["bindings"] = "bindings";
SeparatedPropsMode["extra"] = "extra";
SeparatedPropsMode["hooks"] = "hooks";
SeparatedPropsMode["handlers"] = "handlers";
SeparatedPropsMode["validatedWith"] = "validatedWith";
SeparatedPropsMode["validators"] = "validators";
SeparatedPropsMode["observers"] = "observers";
SeparatedPropsMode["interceptors"] = "interceptors";
SeparatedPropsMode["converters"] = "converters";
SeparatedPropsMode["input"] = "input";
SeparatedPropsMode["output"] = "output";
SeparatedPropsMode["autoFocus"] = "autoFocus";
SeparatedPropsMode["inputMode"] = "inputMode";
SeparatedPropsMode["refs"] = "refs";
SeparatedPropsMode["classes"] = "classes";
SeparatedPropsMode["nullable"] = "nullable";
SeparatedPropsMode["autoComplete"] = "autoComplete";
})(SeparatedPropsMode = exports.SeparatedPropsMode || (exports.SeparatedPropsMode = {}));
/***/ }),
/***/ "./src/models/OptionsModel.ts":
/*!************************************!*\
!*** ./src/models/OptionsModel.ts ***!
\************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OptionsEnum = void 0;
var OptionsEnum;
(function (OptionsEnum) {
OptionsEnum["uniqueId"] = "uniqueId";
OptionsEnum["fallback"] = "fallback";
OptionsEnum["fallbackValue"] = "fallbackValue";
OptionsEnum["defaultGenericError"] = "defaultGenericError";
OptionsEnum["submitThrowsError"] = "submitThrowsError";
OptionsEnum["showErrorsOnInit"] = "showErrorsOnInit";
OptionsEnum["showErrorsOnSubmit"] = "showErrorsOnSubmit";
OptionsEnum["showErrorsOnBlur"] = "showErrorsOnBlur";
OptionsEnum["showErrorsOnChange"] = "showErrorsOnChange";
OptionsEnum["showErrorsOnClear"] = "showErrorsOnClear";
OptionsEnum["showErrorsOnReset"] = "showErrorsOnReset";
OptionsEnum["validateOnInit"] = "validateOnInit";
OptionsEnum["validateOnSubmit"] = "validateOnSubmit";
OptionsEnum["validateOnBlur"] = "validateOnBlur";
OptionsEnum["validateOnChange"] = "validateOnChange";
OptionsEnum["validateOnChangeAfterInitialBlur"] = "validateOnChangeAfterInitialBlur";
OptionsEnum["validateOnChangeAfterSubmit"] = "validateOnChangeAfterSubmit";
OptionsEnum["validateDisabledFields"] = "validateDisabledFields";
OptionsEnum["validateDeletedFields"] = "validateDeletedFields";
OptionsEnum["validatePristineFields"] = "validatePristineFields";
OptionsEnum["validateTrimmedValue"] = "validateTrimmedValue";
OptionsEnum["validateOnClear"] = "validateOnClear";
OptionsEnum["validateOnReset"] = "validateOnReset";
OptionsEnum["strictSet"] = "strictSet";
OptionsEnum["strictUpdate"] = "strictUpdate";
OptionsEnum["strictDelete"] = "strictDelete";
OptionsEnum["strictSelect"] = "strictSelect";
OptionsEnum["softDelete"] = "softDelete";
OptionsEnum["retrieveOnlyDirtyFieldsValues"] = "retrieveOnlyDirtyFieldsValues";
OptionsEnum["retrieveOnlyEnabledFieldsValues"] = "retrieveOnlyEnabledFieldsValues";
OptionsEnum["retrieveOnlyEnabledFieldsErrors"] = "retrieveOnlyEnabledFieldsErrors";
OptionsEnum["retrieveNullifiedEmptyStrings"] = "retrieveNullifiedEmptyStrings";
OptionsEnum["removeNullishValuesInArrays"] = "removeNullishValuesInArrays";
OptionsEnum["preserveDeletedFieldsValues"] = "preserveDeletedFieldsValues";
OptionsEnum["autoTrimValue"] = "autoTrimValue";
OptionsEnum["autoParseNumbers"] = "autoParseNumbers";
OptionsEnum["validationDebounceWait"] = "validationDebounceWait";
OptionsEnum["validationDebounceOptions"] = "validationDebounceOptions";
OptionsEnum["stopValidationOnError"] = "stopValidationOnError";
OptionsEnum["validationPluginsOrder"] = "validationPluginsOrder";
OptionsEnum["resetValidationBeforeValidate"] = "resetValidationBeforeValidate";
OptionsEnum["applyInputConverterOnInit"] = "applyInputConverterOnInit";
OptionsEnum["applyInputConverterOnSet"] = "applyInputConverterOnSet";
OptionsEnum["applyInputConverterOnUpdate"] = "applyInputConverterOnUpdate";
})(OptionsEnum = exports.OptionsEnum || (exports.OptionsEnum = {}));
/***/ }),
/***/ "./src/models/StateInterface.ts":
/*!**************************************!*\
!*** ./src/models/StateInterface.ts ***!
\**************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.RuntimeMode = void 0;
var RuntimeMode;
(function (RuntimeMode) {
RuntimeMode["mixed"] = "mixed";
RuntimeMode["unified"] = "unified";
RuntimeMode["separated"] = "separated";
})(RuntimeMode = exports.RuntimeMode || (exports.RuntimeMode = {}));
/***/ }),
/***/ "./src/models/ValidatorInterface.ts":
/*!******************************************!*\
!*** ./src/models/ValidatorInterface.ts ***!
\******************************************/
/***/ ((__unused_webpack_module, exports) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ValidationHooks = void 0;
var ValidationHooks;
(function (ValidationHooks) {
ValidationHooks["onSuccess"] = "onSuccess";
ValidationHooks["onError"] = "onError";
})(ValidationHooks = exports.ValidationHooks || (exports.ValidationHooks = {}));
/***/ }),
/***/ "./src/parser.ts":
/*!***********************!*\
!*** ./src/parser.ts ***!
\***********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.pathToFieldsTree = exports.prepareFieldsData = exports.handleFieldsArrayOfStrings = exports.handleFieldsNested = exports.mergeSchemaDefaults = exports.parseCheckOutput = exports.parseCheckArray = exports.parseArrayProp = exports.parsePath = exports.parseInput = exports.defaultValue = void 0;
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const defaultValue = ({ type = undefined, value = undefined, nullable = undefined, isEmptyArray = false, fallbackValueOption = "", }) => {
if (Array.isArray(value) || isEmptyArray)
return [];
if (nullable || lodash_1.default.isDate(value) || type === "date" || type === "datetime-local")
return null;
if (lodash_1.default.isNumber(value) || type === "number")
return 0;
if (lodash_1.default.isBoolean(value) || type === "checkbox")
return false;
if (lodash_1.default.isString(value) || type === "file")
return "";
return fallbackValueOption;
};
exports.defaultValue = defaultValue;
const parsePath = (path) => {
let $path = path;
$path = lodash_1.default.replace($path, new RegExp("\\[", "g"), ".");
$path = lodash_1.default.replace($path, new RegExp("\\]", "g"), "");
return $path;
};
exports.parsePath = parsePath;
const parseInput = (input, { fallbackValueOption = "", type, isEmptyArray, separated, unified, fallback }) => input((0, utils_1.$try)(separated, unified, fallback, defaultValue({
fallbackValueOption,
type,
isEmptyArray,
})));
exports.parseInput = parseInput;
const parseArrayProp = (val, prop, removeNullishValuesInArrays) => {
const values = lodash_1.default.values(val);
const isValProp = [
FieldProps_1.FieldPropsEnum.value,
FieldProps_1.FieldPropsEnum.initial,
FieldProps_1.FieldPropsEnum.default,
].includes(prop);
if (removeNullishValuesInArrays && isValProp) {
return lodash_1.default.without(values, ...[null, undefined, ""]);
}
return values;
};
exports.parseArrayProp = parseArrayProp;
const parseCheckArray = (field, value, prop, removeNullishValuesInArrays) => {
if (field.incremental && lodash_1.default.isObject(value) && lodash_1.default.isEmpty(value))
return [];
return field.hasIncrementalKeys ? parseArrayProp(value, prop, removeNullishValuesInArrays) : value;
};
exports.parseCheckArray = parseCheckArray;
const parseCheckOutput = (field, prop, retrieveNullifiedEmptyStrings = false) => {
if (prop === FieldProps_1.FieldPropsEnum.value || prop.startsWith("value.")) {
const base = field.$output ? field.$output(field[FieldProps_1.FieldPropsEnum.value]) : field[FieldProps_1.FieldPropsEnum.value];
const value = prop.startsWith("value.") ? lodash_1.default.get(base, prop.substring(6)) : base;
if (lodash_1.default.isString(value) && lodash_1.default.isEmpty(value) && retrieveNullifiedEmptyStrings)
return null;
return value;
}
return field[prop];
};
exports.parseCheckOutput = parseCheckOutput;
const defineFieldsFromStruct = (struct, add = false) => lodash_1.default.reduceRight(struct, ($, name) => {
const obj = {};
if (lodash_1.default.endsWith(name, "[]")) {
const val = add ? [$] : [];
obj[lodash_1.default.trimEnd(name, "[]")] = val;
return obj;
}
// no brakets
const prev = struct[struct.indexOf(name) - 1];
const stop = lodash_1.default.endsWith(prev, "[]") && lodash_1.default.last(struct) === name;
if (!add && stop)
return obj;
obj[name] = $;
return obj;
}, {});
const handleFieldsArrayOfStrings = ($fields, add = false) => {
let fields = $fields;
// handle array with field struct (strings)
if ((0, utils_1.isArrayOfStrings)(fields)) {
fields = lodash_1.default.transform(fields, ($obj, $) => {
const pathStruct = lodash_1.default.split($, ".");
// as array of strings (with empty values)
if (!pathStruct.length)
return Object.assign($obj, { [$]: "" });
// define flat or nested fields from pathStruct
return lodash_1.default.merge($obj, defineFieldsFromStruct(pathStruct, add));
}, {});
}
return fields;
};
exports.handleFieldsArrayOfStrings = handleFieldsArrayOfStrings;
const handleFieldsArrayOfObjects = ($fields) => {
let fields = $fields;
// handle array of objects (with unified props)
if ((0, utils_1.isArrayOfObjects)(fields)) {
fields = lodash_1.default.transform(fields, ($obj, field) => {
if ((0, utils_1.hasUnifiedProps)({ fields: { field } }) && !lodash_1.default.has(field, FieldProps_1.FieldPropsEnum.name))
return undefined;
return Object.assign($obj, { [field.name]: field });
}, {});
}
return fields;
};
const handleFieldsNested = (fields, strictProps = true) => lodash_1.default.transform(fields, (obj, field, key) => {
if ((0, utils_1.allowNested)(field, strictProps)) {
// define nested field
return Object.assign(obj, {
[key]: {
fields: (0, utils_1.isEmptyArray)(field) ? [] : handleFieldsNested(field),
},
});
}
return Object.assign(obj, { [key]: field });
}, {});
exports.handleFieldsNested = handleFieldsNested;
/* mapNestedValuesToUnifiedValues
FROM:
{
street: '123 Fake St.',
zip: '12345',
}
TO:
[{
name: 'street'
value: '123 Fake St.',
}, {
name: 'zip'
value: '12345',
}]
*/
const mapNestedValuesToUnifiedValues = (data) => lodash_1.default.isPlainObject(data)
? lodash_1.default.map(data, (value, name) => ({ value, name }))
: undefined;
/* reduceValuesToUnifiedFields
FROM:
{
name: 'fatty',
address: {
street: '123 Fake St.',
zip: '12345',
},
};
TO:
{
name: {
value: 'fatty',
fields: undefined
},
address: {
value: {
street: '123 Fake St.',
zip: '12345'
},
fields: [ ... ]
},
};
*/
const reduceValuesToUnifiedFields = (values) => lodash_1.default.transform(values, (obj, value, key) => Object.assign(obj, {
[key]: {
value,
fields: mapNestedValuesToUnifiedValues(value),
},
}), {});
/*
Fallback Unified Props to Separated Mode
*/
const handleFieldsPropsFallback = (fields, initial, fallback) => {
if (!lodash_1.default.has(initial, FieldProps_1.SeparatedPropsMode.values))
return fields;
// if the 'values' object is passed in constructor
// then update the fields definitions
let { values } = initial;
if ((0, utils_1.hasUnifiedProps)({ fields: initial.fields })) {
values = reduceValuesToUnifiedFields(values);
}
return lodash_1.default.merge(fields, lodash_1.default.transform(values, (result, v, k) => {
if (Array.isArray(fields[k]))
result[k] = v;
if (!(k in fields) && (!isNaN(Number(k)) || fallback))
result[k] = v;
}, {}));
};
const mergeSchemaDefaults = (fields, validator) => {
if (validator) {
const schema = lodash_1.default.get(validator.plugins, "svk.config.schema");
if (lodash_1.default.isEmpty(fields) && schema && !!schema.properties) {
lodash_1.default.each(schema.properties, (prop, key) => {
lodash_1.default.set(fields, key, {
value: prop.default,
label: prop.title,
});
});
}
}
return fields;
};
exports.mergeSchemaDefaults = mergeSchemaDefaults;
const prepareFieldsData = (initial, strictProps = true, fallback = true) => {
let fields = lodash_1.default.merge(handleFieldsArrayOfStrings(initial.fields, false), handleFieldsArrayOfStrings(initial.struct, false));
fields = handleFieldsArrayOfObjects(fields);
fields = handleFieldsPropsFallback(fields, initial, fallback);
fields = handleFieldsNested(fields, strictProps);
return fields;
};
exports.prepareFieldsData = prepareFieldsData;
const pathToFieldsTree = (struct, path, n = 0, add = false) => {
const structPath = (0, utils_1.pathToStruct)(path);
const structArray = lodash_1.default.filter(struct, (item) => lodash_1.default.startsWith(item, structPath));
const $tree = handleFieldsArrayOfStrings(structArray, add);
const $struct = lodash_1.default.replace(structPath, new RegExp("\\[]", "g"), `[${n}]`);
const fields = handleFieldsNested(lodash_1.default.get($tree, $struct));
// fix issues #614 & #615
struct.length && struct
.filter(s => s.startsWith(path + '[]'))
.map(s => s.substring((path + '[].').length))
.filter(s => s.endsWith('[]'))
.map(s => s.substring(0, s.length - 2))
.forEach(s => {
var _a, _b;
const ss = s.split('.');
let t = (_a = fields[0]) === null || _a === void 0 ? void 0 : _a.fields;
for (let i = 0; i < ss.length; i++) {
t = (_b = t === null || t === void 0 ? void 0 : t[ss[i]]) === null || _b === void 0 ? void 0 : _b[FieldProps_1.FieldPropsEnum.fields];
if (!t)
break;
}
if (t)
delete t[0];
});
return fields;
};
exports.pathToFieldsTree = pathToFieldsTree;
/***/ }),
/***/ "./src/props.ts":
/*!**********************!*\
!*** ./src/props.ts ***!
\**********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.props = void 0;
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
exports.props = {
editable: [
FieldProps_1.FieldPropsEnum.type,
FieldProps_1.FieldPropsEnum.value,
FieldProps_1.FieldPropsEnum.initial,
FieldProps_1.FieldPropsEnum.default,
FieldProps_1.FieldPropsEnum.label,
FieldProps_1.FieldPropsEnum.placeholder,
FieldProps_1.FieldPropsEnum.related,
FieldProps_1.FieldPropsEnum.options,
FieldProps_1.FieldPropsEnum.extra,
FieldProps_1.FieldPropsEnum.bindings,
FieldProps_1.FieldPropsEnum.hooks,
FieldProps_1.FieldPropsEnum.handlers,
FieldProps_1.FieldPropsEnum.deleted,
FieldProps_1.FieldPropsEnum.disabled,
FieldProps_1.FieldPropsEnum.autoFocus,
FieldProps_1.FieldPropsEnum.inputMode,
FieldProps_1.FieldPropsEnum.ref,
FieldProps_1.FieldPropsEnum.nullable,
FieldProps_1.FieldPropsEnum.autoComplete,
],
handlers: [
FieldProps_1.FieldPropsEnum.onChange,
FieldProps_1.FieldPropsEnum.onToggle,
FieldProps_1.FieldPropsEnum.onFocus,
FieldProps_1.FieldPropsEnum.onBlur,
FieldProps_1.FieldPropsEnum.onDrop,
FieldProps_1.FieldPropsEnum.onSubmit,
FieldProps_1.FieldPropsEnum.onReset,
FieldProps_1.FieldPropsEnum.onClear,
FieldProps_1.FieldPropsEnum.onAdd,
FieldProps_1.FieldPropsEnum.onDel,
],
computed: [
FieldProps_1.FieldPropsEnum.error,
FieldProps_1.FieldPropsEnum.hasError,
FieldProps_1.FieldPropsEnum.isValid,
FieldProps_1.FieldPropsEnum.isDirty,
FieldProps_1.FieldPropsEnum.isPristine,
FieldProps_1.FieldPropsEnum.isDefault,
FieldProps_1.FieldPropsEnum.isEmpty,
FieldProps_1.FieldPropsEnum.focused,
FieldProps_1.FieldPropsEnum.touched,
FieldProps_1.FieldPropsEnum.changed,
FieldProps_1.FieldPropsEnum.validating,
FieldProps_1.FieldPropsEnum.submitting,
FieldProps_1.FieldPropsEnum.resetting,
FieldProps_1.FieldPropsEnum.clearing,
FieldProps_1.FieldPropsEnum.blurred,
FieldProps_1.FieldPropsEnum.deleted,
FieldProps_1.FieldPropsEnum.disabled,
],
separated: [
FieldProps_1.SeparatedPropsMode.computed,
FieldProps_1.SeparatedPropsMode.values,
FieldProps_1.SeparatedPropsMode.labels,
FieldProps_1.SeparatedPropsMode.placeholders,
FieldProps_1.SeparatedPropsMode.defaults,
FieldProps_1.SeparatedPropsMode.initials,
FieldProps_1.SeparatedPropsMode.disabled,
FieldProps_1.SeparatedPropsMode.deleted,
FieldProps_1.SeparatedPropsMode.types,
FieldProps_1.SeparatedPropsMode.related,
FieldProps_1.SeparatedPropsMode.rules,
FieldProps_1.SeparatedPropsMode.options,
FieldProps_1.SeparatedPropsMode.bindings,
FieldProps_1.SeparatedPropsMode.extra,
FieldProps_1.SeparatedPropsMode.hooks,
FieldProps_1.SeparatedPropsMode.handlers,
FieldProps_1.SeparatedPropsMode.validatedWith,
FieldProps_1.SeparatedPropsMode.validators,
FieldProps_1.SeparatedPropsMode.observers,
FieldProps_1.SeparatedPropsMode.interceptors,
FieldProps_1.SeparatedPropsMode.converters,
FieldProps_1.SeparatedPropsMode.input,
FieldProps_1.SeparatedPropsMode.output,
FieldProps_1.SeparatedPropsMode.autoFocus,
FieldProps_1.SeparatedPropsMode.inputMode,
FieldProps_1.SeparatedPropsMode.refs,
FieldProps_1.SeparatedPropsMode.classes,
FieldProps_1.SeparatedPropsMode.nullable,
FieldProps_1.SeparatedPropsMode.autoComplete,
],
functions: [
FieldProps_1.FieldPropsEnum.computed,
FieldProps_1.FieldPropsEnum.observers,
FieldProps_1.FieldPropsEnum.interceptors,
FieldProps_1.FieldPropsEnum.converter,
FieldProps_1.FieldPropsEnum.input,
FieldProps_1.FieldPropsEnum.output,
],
validation: [
FieldProps_1.FieldPropsEnum.rules,
FieldProps_1.FieldPropsEnum.validators,
FieldProps_1.FieldPropsEnum.validatedWith,
],
occurrences: {
isDirty: FieldProps_1.FieldPropsOccurrence.some,
isPristine: FieldProps_1.FieldPropsOccurrence.every,
isDefault: FieldProps_1.FieldPropsOccurrence.every,
isValid: FieldProps_1.FieldPropsOccurrence.every,
isEmpty: FieldProps_1.FieldPropsOccurrence.every,
hasError: FieldProps_1.FieldPropsOccurrence.some,
focused: FieldProps_1.FieldPropsOccurrence.some,
blurred: FieldProps_1.FieldPropsOccurrence.some,
touched: FieldProps_1.FieldPropsOccurrence.some,
deleted: FieldProps_1.FieldPropsOccurrence.every,
disabled: FieldProps_1.FieldPropsOccurrence.every,
clearing: FieldProps_1.FieldPropsOccurrence.every,
resetting: FieldProps_1.FieldPropsOccurrence.every,
},
};
/***/ }),
/***/ "./src/utils.ts":
/*!**********************!*\
!*** ./src/utils.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getObservableMapValues = exports.getObservableMapKeys = exports.$try = exports.isBool = exports.hasFiles = exports.isEvent = exports.uniqueId = exports.maxKey = exports.hasIntKeys = exports.parseIntKeys = exports.allowNested = exports.hasSeparatedProps = exports.hasUnifiedProps = exports.isArrayFromStruct = exports.pathToStruct = exports.isArrayOfObjects = exports.isEmptyArray = exports.isArrayOfStrings = exports.throwError = exports.allowedProps = exports.hasProps = exports.checkPropOccurrence = exports.checkObserve = exports.props = void 0;
const lodash_1 = __importDefault(__webpack_require__(/*! lodash */ "lodash"));
const mobx_1 = __webpack_require__(/*! mobx */ "mobx");
const FieldProps_1 = __webpack_require__(/*! ./models/FieldProps */ "./src/models/FieldProps.ts");
const props_1 = __webpack_require__(/*! ./props */ "./src/props.ts");
Object.defineProperty(exports, "props", ({ enumerable: true, get: function () { return props_1.props; } }));
const getObservableMapValues = (observableMap) => (0, mobx_1.values)(observableMap);
exports.getObservableMapValues = getObservableMapValues;
const getObservableMapKeys = (observableMap) => (0, mobx_1.keys)(observableMap);
exports.getObservableMapKeys = getObservableMapKeys;
const checkObserveItem = (change) => ({ key, to, type, exec }) => change.type === type &&
change.name === key &&
change.newValue === to &&
exec.apply(change, [change]);
const checkObserve = (collection) => (change) => collection.map(checkObserveItem(change));
exports.checkObserve = checkObserve;
const checkPropOccurrence = ({ type, data }) => {
let $check;
switch (type) {
case FieldProps_1.FieldPropsOccurrence.some:
$check = ($data) => lodash_1.default.some($data, Boolean);
break;
case FieldProps_1.FieldPropsOccurrence.every:
$check = ($data) => lodash_1.default.every($data, Boolean);
break;
default: throw new Error('Occurrence not found for specified prop');
}
return $check(data);
};
exports.checkPropOccurrence = checkPropOccurrence;
const hasProps = ($type, $data) => {
let $props;
switch ($type) {
case FieldProps_1.AllowedFieldPropsTypes.computed:
$props = props_1.props.computed;
break;
case FieldProps_1.AllowedFieldPropsTypes.observable:
$props = [
FieldProps_1.FieldPropsEnum.fields,
...props_1.props.computed,
...props_1.props.editable,
];
break;
case FieldProps_1.AllowedFieldPropsTypes.editable:
$props = [
...props_1.props.editable,
...props_1.props.validation,
...props_1.props.functions,
...props_1.props.handlers,
];
break;
case FieldProps_1.AllowedFieldPropsTypes.all:
$props = [
FieldProps_1.FieldPropsEnum.id,
FieldProps_1.FieldPropsEnum.key,
FieldProps_1.FieldPropsEnum.name,
FieldProps_1.FieldPropsEnum.path,
...props_1.props.computed,
...props_1.props.editable,
...props_1.props.validation,
...props_1.props.functions,
...props_1.props.handlers,
];
break;
default:
$props = null;
}
return lodash_1.default.intersection($data, $props).length > 0;
};
exports.hasProps = hasProps;
/**
Check Allowed Properties
*/
const allowedProps = (type, data) => {
if (hasProps(type, data))
return;
const $msg = "The selected property is not allowed";
throw new Error(`${$msg} (${JSON.stringify(data)})`);
};
exports.allowedProps = allowedProps;
/**
Throw Error if undefined Fields
*/
const throwError = (path, fields, msg = null) => {
if (!lodash_1.default.isNil(fields))
return;
const $msg = lodash_1.default.isNil(msg) ? "The selected field is not defined" : msg;
throw new Error(`${$msg} (${path})`);
};
exports.throwError = throwError;
const pathToStruct = (path) => {
let struct;
struct = lodash_1.default.replace(path, new RegExp("[.]\\d+($|.)", "g"), "[].");
struct = lodash_1.default.replace(struct, "..", ".");
struct = lodash_1.default.trim(struct, ".");
return struct;
};
exports.pathToStruct = pathToStruct;
const isArrayFromStruct = (struct, structPath) => {
if (isArrayOfStrings(struct))
return !!struct
.filter((s) => s.startsWith(structPath))
.find((s) => s.substring(structPath.length) === "[]")
|| lodash_1.default.endsWith(struct === null || struct === void 0 ? void 0 : struct.find((e) => e === structPath), '[]');
else
return false;
};
exports.isArrayFromStruct = isArrayFromStruct;
const hasSome = (obj, keys) => lodash_1.default.some(keys, lodash_1.default.partial(lodash_1.default.has, obj));
const isEmptyArray = (field) => lodash_1.default.isEmpty(field) && Array.isArray(field);
exports.isEmptyArray = isEmptyArray;
const isArrayOfStrings = (struct) => Array.isArray(struct) && lodash_1.default.every(struct, lodash_1.default.isString);
exports.isArrayOfStrings = isArrayOfStrings;
const isArrayOfObjects = (fields) => Array.isArray(fields) && lodash_1.default.every(fields, lodash_1.default.isPlainObject);
exports.isArrayOfObjects = isArrayOfObjects;
const getKeys = (fields) => lodash_1.default.union(...lodash_1.default.map(lodash_1.default.values(fields), (values) => lodash_1.default.keys(values)));
const hasUnifiedProps = ({ fields }) => !isArrayOfStrings({ fields }) && hasProps(FieldProps_1.AllowedFieldPropsTypes.editable, getKeys(fields));
exports.hasUnifiedProps = hasUnifiedProps;
const hasSeparatedProps = (initial) => hasSome(initial, props_1.props.separated) || hasSome(initial, props_1.props.validation);
exports.hasSeparatedProps = hasSeparatedProps;
const allowNested = (field, strictProps) => lodash_1.default.isObject(field) &&
!lodash_1.default.isDate(field) &&
!lodash_1.default.has(field, FieldProps_1.FieldPropsEnum.fields) &&
!lodash_1.default.has(field, FieldProps_1.FieldPropsEnum.class) &&
(!hasSome(field, [
...props_1.props.editable,
...props_1.props.handlers,
...props_1.props.validation,
...props_1.props.functions,
]) || strictProps);
exports.allowNested = allowNested;
const parseIntKeys = (fields) => lodash_1.default.map(getObservableMapKeys(fields), lodash_1.default.ary(lodash_1.default.toNumber, 1));
exports.parseIntKeys = parseIntKeys;
const hasIntKeys = (fields) => lodash_1.default.every(parseIntKeys(fields), lodash_1.default.isInteger);
exports.hasIntKeys = hasIntKeys;
const maxKey = (fields) => {
const max = lodash_1.default.max(parseIntKeys(fields));
return lodash_1.default.isUndefined(max) ? 0 : max + 1;
};
exports.maxKey = maxKey;
const uniqueId = (field) => lodash_1.default.uniqueId([lodash_1.default.replace(field.path, new RegExp("\\.", "g"), "-"), "--"].join(""));
exports.uniqueId = uniqueId;
const isEvent = (obj) => {
if (lodash_1.default.isNil(obj) || typeof Event === "undefined")
return false;
return obj instanceof Event || !lodash_1.default.isNil(obj.target);
};
exports.isEvent = isEvent;
const hasFiles = ($) => $.target.files && $.target.files.length !== 0;
exports.hasFiles = hasFiles;
const isBool = ($, val) => lodash_1.default.isBoolean(val) && lodash_1.default.isBoolean($.target.checked);
exports.isBool = isBool;
const $try = (...args) => {
let found = undefined;
args.map((val) => found === undefined && !lodash_1.default.isUndefined(val) && (found = val));
return found;
};
exports.$try = $try;
/***/ }),
/***/ "lodash":
/*!********************!*\
!*** external "_" ***!
\********************/
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE_lodash__;
/***/ }),
/***/ "mobx":
/*!***********************!*\
!*** external "mobx" ***!
\***********************/
/***/ ((module) => {
module.exports = __WEBPACK_EXTERNAL_MODULE_mobx__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./src/index.ts");
/******/
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=MobxReactForm.umd.js.map