From 67fef53afe1183e5753dab51c2d2e32d4f2e5514 Mon Sep 17 00:00:00 2001 From: Claudio Savino Date: Fri, 14 Jul 2023 11:36:38 +0200 Subject: [PATCH] fix: isArrayFromStruct isArrayFromStruct --- CHANGELOG.md | 5 +++++ src/Base.ts | 7 ++++--- src/Field.ts | 32 +++++++++++++++----------------- src/models/FieldInterface.ts | 4 +++- src/parser.ts | 4 ++-- src/utils.ts | 15 ++++++++++++--- src/validators/VJF.ts | 4 ++-- 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85f95f45..dfc5522b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 6.3.4 (master) +- Fix: `isEmptyArray` reimplemented in `isArrayFromStruct` util function; +- Removed lodash `_.isArray()` with `Array.isArray()` +- Introduced `struct` prop in `makeField` method. + # 6.3.3 (master) - Fix: `get('value')` retrieve empty array removed by `update()` - Fix: `composer` returned in `validate/submit` instead of single methods. diff --git a/src/Base.ts b/src/Base.ts index 6e38f925..f687cc4c 100755 --- a/src/Base.ts +++ b/src/Base.ts @@ -307,6 +307,7 @@ export default class Base implements BaseInterface { const field = this.state.form.makeField({ key, path, + struct, data, props, update, @@ -393,7 +394,7 @@ export default class Base implements BaseInterface { return _.transform( $fields, (check: any, field: any) => { - if (!field.fields.size || !_.isArray(field.initial)) { + if (!field.fields.size || !Array.isArray(field.initial)) { check.push(field[prop]); } @@ -436,7 +437,7 @@ export default class Base implements BaseInterface { const applyInputConverterOnUpdate = this.state.options.get(OptionsEnum.applyInputConverterOnUpdate, this); if (!_.isNil($field) && !_.isUndefined(field)) { - if (_.isArray($field.values())) { + if (Array.isArray($field.values())) { const n: number = _.max(_.map(field.fields, (f, i) => Number(i))) ?? -1; _.each(getObservableMapValues($field.fields), ($f) => { if (Number($f.name) > n) { @@ -498,7 +499,7 @@ export default class Base implements BaseInterface { ); } - allowedProps(AllowedFieldPropsTypes.all, _.isArray(prop) ? prop : [prop]); + allowedProps(AllowedFieldPropsTypes.all, Array.isArray(prop) ? prop : [prop]); if (_.isString(prop)) { if (strict && this.fields.size === 0) { diff --git a/src/Field.ts b/src/Field.ts index 047a6c13..5cd79fe7 100755 --- a/src/Field.ts +++ b/src/Field.ts @@ -12,7 +12,7 @@ import { import _ from "lodash"; import Base from "./Base"; -import { $try, $hasFiles, $isBool, $isEvent, pathToStruct } from "./utils"; +import { $try, $hasFiles, $isBool, $isEvent, pathToStruct, isArrayFromStruct } from "./utils"; import { parseInput, @@ -177,6 +177,7 @@ export default class Field extends Base implements FieldInterface { constructor({ key, path, + struct, data = {}, props = {}, update = false, @@ -255,7 +256,7 @@ export default class Field extends Base implements FieldInterface { this.state = state; - this.setupField(key, path, data, props, update); + this.setupField(key, path, struct, data, props, update); this.checkValidationPlugins(); this.initNestedFields(data, update); @@ -564,6 +565,7 @@ export default class Field extends Base implements FieldInterface { setupField( $key: string, $path: string, + $struct: string, $data: any, $props: any, update: boolean @@ -571,15 +573,11 @@ export default class Field extends Base implements FieldInterface { this.key = $key; this.path = $path; this.id = this.state.options.get(OptionsEnum.uniqueId)?.apply(this, [this]); - const fallbackValueOption = this.state.options.get(OptionsEnum.fallbackValue, this); - const applyInputConverterOnInit = this.state.options.get(OptionsEnum.applyInputConverterOnInit, this); - const struct = this.state.struct(); - const structPath = pathToStruct(this.path); - const isEmptyArray: boolean = Array.isArray(struct) - ? !!struct - .filter((s) => s.startsWith(structPath)) - .find((s) => s.substring(structPath.length) === "[]") - : !!Array.isArray(_.get(struct, this.path)); + const fallbackValueOption: any = this.state.options.get(OptionsEnum.fallbackValue, this); + const applyInputConverterOnInit: boolean = this.state.options.get(OptionsEnum.applyInputConverterOnInit, this); + const struct: string[] = this.state.struct(); + const structPath: string = pathToStruct(this.path); + const isEmptyArray: boolean = isArrayFromStruct(struct, structPath); const { $type, $input, $output, $converter, $computed } = $props; @@ -671,7 +669,7 @@ export default class Field extends Base implements FieldInterface { // @ts-ignore const val = this[`$${key}`]; - if (_.isArray(val) || isObservableArray(val)) { + if (Array.isArray(val) || isObservableArray(val)) { return [].slice.call(val); } @@ -702,14 +700,14 @@ export default class Field extends Base implements FieldInterface { initNestedFields(field: any, update: boolean): void { const fields = _.isNil(field) ? null : field.fields; - if (_.isArray(fields) && !_.isEmpty(fields)) { + if (Array.isArray(fields) && !_.isEmpty(fields)) { this.hasInitialNestedFields = true; } this.initFields({ fields }, update); - if (!update && _.isArray(fields) && _.isEmpty(fields)) { - if (_.isArray(this.value) && !_.isEmpty(this.value)) { + if (!update && Array.isArray(fields) && _.isEmpty(fields)) { + if (Array.isArray(this.value) && !_.isEmpty(this.value)) { this.hasInitialNestedFields = true; this.initFields({ fields, values: this.value }, update); } @@ -722,7 +720,7 @@ export default class Field extends Base implements FieldInterface { return; } - if (_.isArray(message)) { + if (Array.isArray(message)) { this.validationErrorStack = message; this.showErrors(true); return; @@ -870,7 +868,7 @@ export default class Field extends Base implements FieldInterface { } initMOBXEvent(type: string): void { - if (!_.isArray(this[`$${type}`])) return; + if (!Array.isArray(this[`$${type}`])) return; let fn: any; if (type === FieldPropsEnum.observers) fn = this.observe; diff --git a/src/models/FieldInterface.ts b/src/models/FieldInterface.ts index 12429765..b8deb215 100644 --- a/src/models/FieldInterface.ts +++ b/src/models/FieldInterface.ts @@ -58,6 +58,7 @@ export default interface FieldInterface extends BaseInterface { setupField( key: string, path: string, + struct: string, data: any, props: any, update: boolean @@ -82,7 +83,8 @@ export default interface FieldInterface extends BaseInterface { export interface FieldConstructor { key: string; - path: string; + path?: string; + struct?: string; data?: any; props?: any; update?: boolean; diff --git a/src/parser.ts b/src/parser.ts index f5b3ed8a..cbf365d2 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -16,7 +16,7 @@ const defaultValue = ({ isEmptyArray = false, fallbackValueOption = "", }: any): null | false | 0 | [] | "" => { - if (_.isArray(value) || isEmptyArray) return []; + if (Array.isArray(value) || isEmptyArray) return []; if (_.isDate(value) || type === "date" || type === "datetime-local") return null; if (_.isNumber(value) || type === "number") return 0; if (_.isBoolean(value) || type === "checkbox") return false; @@ -237,7 +237,7 @@ const handleFieldsPropsFallback = ( _.transform( values, (result: any, v, k) => { - if (_.isArray(fields[k])) result[k] = v; + if (Array.isArray(fields[k])) result[k] = v; if (!(k in fields) && (!isNaN(Number(k)) || fallback)) result[k] = v; }, {} diff --git a/src/utils.ts b/src/utils.ts index a2c55124..3cd47385 100755 --- a/src/utils.ts +++ b/src/utils.ts @@ -98,17 +98,25 @@ const pathToStruct = (path: string): string => { return struct; }; +const isArrayFromStruct = (struct: string[], structPath: string): boolean => { + if (isArrayOfStrings(struct)) return !!struct + .filter((s) => s.startsWith(structPath)) + .find((s) => s.substring(structPath.length) === "[]") + || _.endsWith(struct?.find((e) => e === structPath), '[]'); + else return false; +}; + const hasSome = (obj: any, keys: any): boolean => _.some(keys, _.partial(_.has, obj)); const isEmptyArray = (field: any): boolean => - _.isEmpty(field) && _.isArray(field); + _.isEmpty(field) && Array.isArray(field); const isArrayOfStrings = (struct: any): boolean => - _.isArray(struct) && _.every(struct, _.isString); + Array.isArray(struct) && _.every(struct, _.isString); const isArrayOfObjects = (fields: any): boolean => - _.isArray(fields) && _.every(fields, _.isPlainObject); + Array.isArray(fields) && _.every(fields, _.isPlainObject); const getKeys = (fields: any) => _.union(..._.map(_.values(fields), (values) => _.keys(values))); @@ -178,6 +186,7 @@ export { isEmptyArray, isArrayOfObjects, pathToStruct, + isArrayFromStruct, hasUnifiedProps, hasSeparatedProps, allowNested, diff --git a/src/validators/VJF.ts b/src/validators/VJF.ts index 28630467..74980e9d 100755 --- a/src/validators/VJF.ts +++ b/src/validators/VJF.ts @@ -59,7 +59,7 @@ export class VJF implements ValidationPluginInterface { // get validators from validate property const $fn = field.validators; // map only if is an array of validator functions - if (_.isArray($fn)) { + if (Array.isArray($fn)) { $fn.map((fn) => this.collectData(fn, field)); } // it's just one function // DEPRECATED @@ -113,7 +113,7 @@ export class VJF implements ValidationPluginInterface { /** Handle "array" */ - if (_.isArray(res)) { + if (Array.isArray(res)) { const isValid = res[0] || false; const message = res[1] || "Error"; return [isValid, message];