@flowerforce/flower-core 3.0.1-beta.7 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/index.cjs.js +12 -159
- package/dist/index.esm.js +11 -158
- package/dist/src/RulesMatcher.d.ts +2 -1
- package/dist/src/interfaces/CoreInterface.d.ts +2 -1
- package/dist/src/interfaces/SelectorsInterface.d.ts +2 -2
- package/dist/src/interfaces/Store.d.ts +2 -2
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 3.1.0 (2024-06-06)
|
2
|
+
|
3
|
+
|
4
|
+
### 🚀 Features
|
5
|
+
|
6
|
+
- add restart action in core ([800da33](https://github.com/flowerforce/flower/commit/800da33))
|
7
|
+
|
8
|
+
- add devtool to demo - remove duplicated export type ([88117d6](https://github.com/flowerforce/flower/commit/88117d6))
|
9
|
+
|
10
|
+
- allow custom functions when defining rules and navigation between nodes ([b35f5da](https://github.com/flowerforce/flower/commit/b35f5da))
|
11
|
+
|
12
|
+
|
13
|
+
### 🩹 Fixes
|
14
|
+
|
15
|
+
- fix circular dependency on rules matchers ([0bcb02f](https://github.com/flowerforce/flower/commit/0bcb02f))
|
16
|
+
|
17
|
+
- align packages ([210a284](https://github.com/flowerforce/flower/commit/210a284))
|
18
|
+
|
1
19
|
## 3.0.0 (2024-05-20)
|
2
20
|
|
3
21
|
This was a version bump only for flower-core to align it with other projects, there were no code changes.
|
package/dist/index.cjs.js
CHANGED
@@ -18,6 +18,7 @@ var mapKeys = require('lodash/mapKeys');
|
|
18
18
|
var mapValues = require('lodash/mapValues');
|
19
19
|
var _trimStart = require('lodash/trimStart');
|
20
20
|
var _intersection = require('lodash/intersection');
|
21
|
+
var flat = require('flat');
|
21
22
|
|
22
23
|
const Emitter = new tinyEmitter.TinyEmitter();
|
23
24
|
|
@@ -190,6 +191,7 @@ const rulesMatcherUtils = {
|
|
190
191
|
},
|
191
192
|
getKeys: (rules, options) => {
|
192
193
|
if (!rules) return null;
|
194
|
+
if (typeof rules == 'function') return [];
|
193
195
|
if (!rulesMatcherUtils.forceArray(rules).every(r => rulesMatcherUtils.isObject(r))) return null;
|
194
196
|
const keys = {};
|
195
197
|
const conditions = Array.isArray(rules) ? {
|
@@ -219,6 +221,9 @@ const operators = {
|
|
219
221
|
|
220
222
|
const rulesMatcher = (rules, formValue = {}, apply = true, options) => {
|
221
223
|
if (!rules) return [apply];
|
224
|
+
if (typeof rules === 'function') {
|
225
|
+
return [rules(formValue) === apply];
|
226
|
+
}
|
222
227
|
const conditions = Array.isArray(rules) ? {
|
223
228
|
$and: rules
|
224
229
|
} : rules;
|
@@ -347,6 +352,9 @@ const CoreUtils = {
|
|
347
352
|
if (typeof rule.rules === 'string') {
|
348
353
|
return false;
|
349
354
|
}
|
355
|
+
if (typeof rule.rules === 'function') {
|
356
|
+
return rule.rules(value);
|
357
|
+
}
|
350
358
|
if (rule.rules === null) {
|
351
359
|
return true;
|
352
360
|
}
|
@@ -750,164 +758,6 @@ const FlowerCoreReducers = {
|
|
750
758
|
}
|
751
759
|
};
|
752
760
|
|
753
|
-
function isBuffer (obj) {
|
754
|
-
return obj &&
|
755
|
-
obj.constructor &&
|
756
|
-
(typeof obj.constructor.isBuffer === 'function') &&
|
757
|
-
obj.constructor.isBuffer(obj)
|
758
|
-
}
|
759
|
-
|
760
|
-
function keyIdentity (key) {
|
761
|
-
return key
|
762
|
-
}
|
763
|
-
|
764
|
-
function flatten (target, opts) {
|
765
|
-
opts = opts || {};
|
766
|
-
|
767
|
-
const delimiter = opts.delimiter || '.';
|
768
|
-
const maxDepth = opts.maxDepth;
|
769
|
-
const transformKey = opts.transformKey || keyIdentity;
|
770
|
-
const output = {};
|
771
|
-
|
772
|
-
function step (object, prev, currentDepth) {
|
773
|
-
currentDepth = currentDepth || 1;
|
774
|
-
Object.keys(object).forEach(function (key) {
|
775
|
-
const value = object[key];
|
776
|
-
const isarray = opts.safe && Array.isArray(value);
|
777
|
-
const type = Object.prototype.toString.call(value);
|
778
|
-
const isbuffer = isBuffer(value);
|
779
|
-
const isobject = (
|
780
|
-
type === '[object Object]' ||
|
781
|
-
type === '[object Array]'
|
782
|
-
);
|
783
|
-
|
784
|
-
const newKey = prev
|
785
|
-
? prev + delimiter + transformKey(key)
|
786
|
-
: transformKey(key);
|
787
|
-
|
788
|
-
if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
|
789
|
-
(!opts.maxDepth || currentDepth < maxDepth)) {
|
790
|
-
return step(value, newKey, currentDepth + 1)
|
791
|
-
}
|
792
|
-
|
793
|
-
output[newKey] = value;
|
794
|
-
});
|
795
|
-
}
|
796
|
-
|
797
|
-
step(target);
|
798
|
-
|
799
|
-
return output
|
800
|
-
}
|
801
|
-
|
802
|
-
function unflatten (target, opts) {
|
803
|
-
opts = opts || {};
|
804
|
-
|
805
|
-
const delimiter = opts.delimiter || '.';
|
806
|
-
const overwrite = opts.overwrite || false;
|
807
|
-
const transformKey = opts.transformKey || keyIdentity;
|
808
|
-
const result = {};
|
809
|
-
|
810
|
-
const isbuffer = isBuffer(target);
|
811
|
-
if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
|
812
|
-
return target
|
813
|
-
}
|
814
|
-
|
815
|
-
// safely ensure that the key is
|
816
|
-
// an integer.
|
817
|
-
function getkey (key) {
|
818
|
-
const parsedKey = Number(key);
|
819
|
-
|
820
|
-
return (
|
821
|
-
isNaN(parsedKey) ||
|
822
|
-
key.indexOf('.') !== -1 ||
|
823
|
-
opts.object
|
824
|
-
)
|
825
|
-
? key
|
826
|
-
: parsedKey
|
827
|
-
}
|
828
|
-
|
829
|
-
function addKeys (keyPrefix, recipient, target) {
|
830
|
-
return Object.keys(target).reduce(function (result, key) {
|
831
|
-
result[keyPrefix + delimiter + key] = target[key];
|
832
|
-
|
833
|
-
return result
|
834
|
-
}, recipient)
|
835
|
-
}
|
836
|
-
|
837
|
-
function isEmpty (val) {
|
838
|
-
const type = Object.prototype.toString.call(val);
|
839
|
-
const isArray = type === '[object Array]';
|
840
|
-
const isObject = type === '[object Object]';
|
841
|
-
|
842
|
-
if (!val) {
|
843
|
-
return true
|
844
|
-
} else if (isArray) {
|
845
|
-
return !val.length
|
846
|
-
} else if (isObject) {
|
847
|
-
return !Object.keys(val).length
|
848
|
-
}
|
849
|
-
}
|
850
|
-
|
851
|
-
target = Object.keys(target).reduce(function (result, key) {
|
852
|
-
const type = Object.prototype.toString.call(target[key]);
|
853
|
-
const isObject = (type === '[object Object]' || type === '[object Array]');
|
854
|
-
if (!isObject || isEmpty(target[key])) {
|
855
|
-
result[key] = target[key];
|
856
|
-
return result
|
857
|
-
} else {
|
858
|
-
return addKeys(
|
859
|
-
key,
|
860
|
-
result,
|
861
|
-
flatten(target[key], opts)
|
862
|
-
)
|
863
|
-
}
|
864
|
-
}, {});
|
865
|
-
|
866
|
-
Object.keys(target).forEach(function (key) {
|
867
|
-
const split = key.split(delimiter).map(transformKey);
|
868
|
-
let key1 = getkey(split.shift());
|
869
|
-
let key2 = getkey(split[0]);
|
870
|
-
let recipient = result;
|
871
|
-
|
872
|
-
while (key2 !== undefined) {
|
873
|
-
if (key1 === '__proto__') {
|
874
|
-
return
|
875
|
-
}
|
876
|
-
|
877
|
-
const type = Object.prototype.toString.call(recipient[key1]);
|
878
|
-
const isobject = (
|
879
|
-
type === '[object Object]' ||
|
880
|
-
type === '[object Array]'
|
881
|
-
);
|
882
|
-
|
883
|
-
// do not write over falsey, non-undefined values if overwrite is false
|
884
|
-
if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
|
885
|
-
return
|
886
|
-
}
|
887
|
-
|
888
|
-
if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
|
889
|
-
recipient[key1] = (
|
890
|
-
typeof key2 === 'number' &&
|
891
|
-
!opts.object
|
892
|
-
? []
|
893
|
-
: {}
|
894
|
-
);
|
895
|
-
}
|
896
|
-
|
897
|
-
recipient = recipient[key1];
|
898
|
-
if (split.length > 0) {
|
899
|
-
key1 = getkey(split.shift());
|
900
|
-
key2 = getkey(split[0]);
|
901
|
-
}
|
902
|
-
}
|
903
|
-
|
904
|
-
// unflatten again for 'messy objects'
|
905
|
-
recipient[key1] = unflatten(target[key], opts);
|
906
|
-
});
|
907
|
-
|
908
|
-
return result
|
909
|
-
}
|
910
|
-
|
911
761
|
const FlowerCoreStateSelectors = {
|
912
762
|
selectGlobal: state => state && state.flower,
|
913
763
|
selectFlower: name => state => _get(state, [name]),
|
@@ -966,6 +816,9 @@ const FlowerCoreStateSelectors = {
|
|
966
816
|
$self: _get(newState, [flowName, ...id.split('.')])
|
967
817
|
} : {});
|
968
818
|
if (!rules) return false;
|
819
|
+
if (typeof rules === 'function') {
|
820
|
+
return !rules(state);
|
821
|
+
}
|
969
822
|
if (!keys) return false;
|
970
823
|
const res = keys.reduce((acc, inc) => {
|
971
824
|
const k = inc;
|
@@ -974,7 +827,7 @@ const FlowerCoreStateSelectors = {
|
|
974
827
|
});
|
975
828
|
}, {});
|
976
829
|
const [disabled] = MatchRules.rulesMatcher(rules, {
|
977
|
-
...unflatten(res)
|
830
|
+
...flat.unflatten(res)
|
978
831
|
}, false, {
|
979
832
|
prefix: flowName
|
980
833
|
});
|
package/dist/index.esm.js
CHANGED
@@ -16,6 +16,7 @@ import mapKeys from 'lodash/mapKeys';
|
|
16
16
|
import mapValues from 'lodash/mapValues';
|
17
17
|
import _trimStart from 'lodash/trimStart';
|
18
18
|
import _intersection from 'lodash/intersection';
|
19
|
+
import { unflatten } from 'flat';
|
19
20
|
|
20
21
|
const Emitter = new TinyEmitter();
|
21
22
|
|
@@ -188,6 +189,7 @@ const rulesMatcherUtils = {
|
|
188
189
|
},
|
189
190
|
getKeys: (rules, options) => {
|
190
191
|
if (!rules) return null;
|
192
|
+
if (typeof rules == 'function') return [];
|
191
193
|
if (!rulesMatcherUtils.forceArray(rules).every(r => rulesMatcherUtils.isObject(r))) return null;
|
192
194
|
const keys = {};
|
193
195
|
const conditions = Array.isArray(rules) ? {
|
@@ -217,6 +219,9 @@ const operators = {
|
|
217
219
|
|
218
220
|
const rulesMatcher = (rules, formValue = {}, apply = true, options) => {
|
219
221
|
if (!rules) return [apply];
|
222
|
+
if (typeof rules === 'function') {
|
223
|
+
return [rules(formValue) === apply];
|
224
|
+
}
|
220
225
|
const conditions = Array.isArray(rules) ? {
|
221
226
|
$and: rules
|
222
227
|
} : rules;
|
@@ -345,6 +350,9 @@ const CoreUtils = {
|
|
345
350
|
if (typeof rule.rules === 'string') {
|
346
351
|
return false;
|
347
352
|
}
|
353
|
+
if (typeof rule.rules === 'function') {
|
354
|
+
return rule.rules(value);
|
355
|
+
}
|
348
356
|
if (rule.rules === null) {
|
349
357
|
return true;
|
350
358
|
}
|
@@ -748,164 +756,6 @@ const FlowerCoreReducers = {
|
|
748
756
|
}
|
749
757
|
};
|
750
758
|
|
751
|
-
function isBuffer (obj) {
|
752
|
-
return obj &&
|
753
|
-
obj.constructor &&
|
754
|
-
(typeof obj.constructor.isBuffer === 'function') &&
|
755
|
-
obj.constructor.isBuffer(obj)
|
756
|
-
}
|
757
|
-
|
758
|
-
function keyIdentity (key) {
|
759
|
-
return key
|
760
|
-
}
|
761
|
-
|
762
|
-
function flatten (target, opts) {
|
763
|
-
opts = opts || {};
|
764
|
-
|
765
|
-
const delimiter = opts.delimiter || '.';
|
766
|
-
const maxDepth = opts.maxDepth;
|
767
|
-
const transformKey = opts.transformKey || keyIdentity;
|
768
|
-
const output = {};
|
769
|
-
|
770
|
-
function step (object, prev, currentDepth) {
|
771
|
-
currentDepth = currentDepth || 1;
|
772
|
-
Object.keys(object).forEach(function (key) {
|
773
|
-
const value = object[key];
|
774
|
-
const isarray = opts.safe && Array.isArray(value);
|
775
|
-
const type = Object.prototype.toString.call(value);
|
776
|
-
const isbuffer = isBuffer(value);
|
777
|
-
const isobject = (
|
778
|
-
type === '[object Object]' ||
|
779
|
-
type === '[object Array]'
|
780
|
-
);
|
781
|
-
|
782
|
-
const newKey = prev
|
783
|
-
? prev + delimiter + transformKey(key)
|
784
|
-
: transformKey(key);
|
785
|
-
|
786
|
-
if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
|
787
|
-
(!opts.maxDepth || currentDepth < maxDepth)) {
|
788
|
-
return step(value, newKey, currentDepth + 1)
|
789
|
-
}
|
790
|
-
|
791
|
-
output[newKey] = value;
|
792
|
-
});
|
793
|
-
}
|
794
|
-
|
795
|
-
step(target);
|
796
|
-
|
797
|
-
return output
|
798
|
-
}
|
799
|
-
|
800
|
-
function unflatten (target, opts) {
|
801
|
-
opts = opts || {};
|
802
|
-
|
803
|
-
const delimiter = opts.delimiter || '.';
|
804
|
-
const overwrite = opts.overwrite || false;
|
805
|
-
const transformKey = opts.transformKey || keyIdentity;
|
806
|
-
const result = {};
|
807
|
-
|
808
|
-
const isbuffer = isBuffer(target);
|
809
|
-
if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
|
810
|
-
return target
|
811
|
-
}
|
812
|
-
|
813
|
-
// safely ensure that the key is
|
814
|
-
// an integer.
|
815
|
-
function getkey (key) {
|
816
|
-
const parsedKey = Number(key);
|
817
|
-
|
818
|
-
return (
|
819
|
-
isNaN(parsedKey) ||
|
820
|
-
key.indexOf('.') !== -1 ||
|
821
|
-
opts.object
|
822
|
-
)
|
823
|
-
? key
|
824
|
-
: parsedKey
|
825
|
-
}
|
826
|
-
|
827
|
-
function addKeys (keyPrefix, recipient, target) {
|
828
|
-
return Object.keys(target).reduce(function (result, key) {
|
829
|
-
result[keyPrefix + delimiter + key] = target[key];
|
830
|
-
|
831
|
-
return result
|
832
|
-
}, recipient)
|
833
|
-
}
|
834
|
-
|
835
|
-
function isEmpty (val) {
|
836
|
-
const type = Object.prototype.toString.call(val);
|
837
|
-
const isArray = type === '[object Array]';
|
838
|
-
const isObject = type === '[object Object]';
|
839
|
-
|
840
|
-
if (!val) {
|
841
|
-
return true
|
842
|
-
} else if (isArray) {
|
843
|
-
return !val.length
|
844
|
-
} else if (isObject) {
|
845
|
-
return !Object.keys(val).length
|
846
|
-
}
|
847
|
-
}
|
848
|
-
|
849
|
-
target = Object.keys(target).reduce(function (result, key) {
|
850
|
-
const type = Object.prototype.toString.call(target[key]);
|
851
|
-
const isObject = (type === '[object Object]' || type === '[object Array]');
|
852
|
-
if (!isObject || isEmpty(target[key])) {
|
853
|
-
result[key] = target[key];
|
854
|
-
return result
|
855
|
-
} else {
|
856
|
-
return addKeys(
|
857
|
-
key,
|
858
|
-
result,
|
859
|
-
flatten(target[key], opts)
|
860
|
-
)
|
861
|
-
}
|
862
|
-
}, {});
|
863
|
-
|
864
|
-
Object.keys(target).forEach(function (key) {
|
865
|
-
const split = key.split(delimiter).map(transformKey);
|
866
|
-
let key1 = getkey(split.shift());
|
867
|
-
let key2 = getkey(split[0]);
|
868
|
-
let recipient = result;
|
869
|
-
|
870
|
-
while (key2 !== undefined) {
|
871
|
-
if (key1 === '__proto__') {
|
872
|
-
return
|
873
|
-
}
|
874
|
-
|
875
|
-
const type = Object.prototype.toString.call(recipient[key1]);
|
876
|
-
const isobject = (
|
877
|
-
type === '[object Object]' ||
|
878
|
-
type === '[object Array]'
|
879
|
-
);
|
880
|
-
|
881
|
-
// do not write over falsey, non-undefined values if overwrite is false
|
882
|
-
if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
|
883
|
-
return
|
884
|
-
}
|
885
|
-
|
886
|
-
if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
|
887
|
-
recipient[key1] = (
|
888
|
-
typeof key2 === 'number' &&
|
889
|
-
!opts.object
|
890
|
-
? []
|
891
|
-
: {}
|
892
|
-
);
|
893
|
-
}
|
894
|
-
|
895
|
-
recipient = recipient[key1];
|
896
|
-
if (split.length > 0) {
|
897
|
-
key1 = getkey(split.shift());
|
898
|
-
key2 = getkey(split[0]);
|
899
|
-
}
|
900
|
-
}
|
901
|
-
|
902
|
-
// unflatten again for 'messy objects'
|
903
|
-
recipient[key1] = unflatten(target[key], opts);
|
904
|
-
});
|
905
|
-
|
906
|
-
return result
|
907
|
-
}
|
908
|
-
|
909
759
|
const FlowerCoreStateSelectors = {
|
910
760
|
selectGlobal: state => state && state.flower,
|
911
761
|
selectFlower: name => state => _get(state, [name]),
|
@@ -964,6 +814,9 @@ const FlowerCoreStateSelectors = {
|
|
964
814
|
$self: _get(newState, [flowName, ...id.split('.')])
|
965
815
|
} : {});
|
966
816
|
if (!rules) return false;
|
817
|
+
if (typeof rules === 'function') {
|
818
|
+
return !rules(state);
|
819
|
+
}
|
967
820
|
if (!keys) return false;
|
968
821
|
const res = keys.reduce((acc, inc) => {
|
969
822
|
const k = inc;
|
@@ -1,4 +1,5 @@
|
|
1
|
+
import { FunctionRule } from './interfaces';
|
1
2
|
export declare const MatchRules: {
|
2
|
-
rulesMatcher: (rules?: Record<string, any> | Record<string, any>[], formValue?: Record<string, any>, apply?: boolean, options?: Record<string, any>) => boolean[];
|
3
|
+
rulesMatcher: (rules?: Record<string, any> | Record<string, any>[] | FunctionRule, formValue?: Record<string, any>, apply?: boolean, options?: Record<string, any>) => boolean[];
|
3
4
|
utils: import("./rules-matcher/interface").RulesMatcherUtils;
|
4
5
|
};
|
@@ -67,6 +67,7 @@ type RulesWithName = {
|
|
67
67
|
rules: RulesObject<any>;
|
68
68
|
};
|
69
69
|
};
|
70
|
+
export type FunctionRule = (data: Record<string, any>) => boolean;
|
70
71
|
export type RulesObject<T> = RulesValuesType<T> | {
|
71
72
|
[K in keyof typeof RulesModes]: Array<RulesOperatorsInArray<RulesValuesType<T>>> | Array<RulesObject<RulesValuesType<T>>>;
|
72
73
|
} | Array<Exclude<RulesOperatorsInArray<RulesValuesType<T>>, undefined>>;
|
@@ -78,7 +79,7 @@ export type GetPath = (idValue?: string) => {
|
|
78
79
|
export type AllEqual = (...args: Array<number | string | boolean>[]) => boolean;
|
79
80
|
export type FindValidRule<T = Rules<RulesObject<any>>> = (nextRules: {
|
80
81
|
rules: {
|
81
|
-
rules: T;
|
82
|
+
rules: T | FunctionRule;
|
82
83
|
};
|
83
84
|
}, value: Record<string, any>, prefix?: {
|
84
85
|
prefix: string;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { RulesObject } from './CoreInterface';
|
2
|
-
import { Flower, Form,
|
2
|
+
import { Flower, Form, INode } from './Store';
|
3
3
|
export interface ISelectors {
|
4
4
|
selectGlobal<T extends Record<string, any>>(state: {
|
5
5
|
flower: {
|
@@ -18,7 +18,7 @@ export interface ISelectors {
|
|
18
18
|
makeSelectCurrentNodeId<T extends Record<string, any>>(flower: Flower<T>, startNodeId: Flower<T>['startId']): string;
|
19
19
|
makeSelectPrevNodeRetain<T extends Record<string, any>>(nodes: Flower<T>['nodes'], history: Flower<T>['history'], current: Flower<T>['current']): boolean | string | undefined;
|
20
20
|
makeSelectCurrentNodeDisabled<T extends Record<string, any>>(nodes: {
|
21
|
-
[x: string]: Partial<
|
21
|
+
[x: string]: Partial<INode>;
|
22
22
|
}, current: Flower<T>['current']): boolean;
|
23
23
|
makeSelectNodeErrors<T extends Record<string, any>>(form: Form<T> | undefined): {
|
24
24
|
touched: boolean;
|
@@ -27,7 +27,7 @@ export interface Flower<T extends Record<string, any>> {
|
|
27
27
|
current: string;
|
28
28
|
history: string[];
|
29
29
|
nodes: {
|
30
|
-
[x: string]:
|
30
|
+
[x: string]: INode;
|
31
31
|
};
|
32
32
|
nextRules: {
|
33
33
|
[x: string]: RulesByNodeId<T>[];
|
@@ -37,7 +37,7 @@ export interface Flower<T extends Record<string, any>> {
|
|
37
37
|
[x: string]: Form<T>;
|
38
38
|
};
|
39
39
|
}
|
40
|
-
export interface
|
40
|
+
export interface INode {
|
41
41
|
nodeId: string;
|
42
42
|
nodeType: string;
|
43
43
|
retain?: boolean;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@flowerforce/flower-core",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.1.0",
|
4
4
|
"description": "Core functions for flowerJS",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -25,12 +25,14 @@
|
|
25
25
|
"lodash": ">=4"
|
26
26
|
},
|
27
27
|
"devDependencies": {
|
28
|
+
"@types/flat": "^5.0.5",
|
28
29
|
"@types/lodash": "^4.17.1",
|
29
30
|
"jest": "^29.7.0",
|
30
31
|
"ts-jest": "^29.1.2",
|
31
32
|
"typescript": "^5.4.5"
|
32
33
|
},
|
33
34
|
"dependencies": {
|
35
|
+
"flat": "5.0.2",
|
34
36
|
"tiny-emitter": "^2.1.0"
|
35
37
|
},
|
36
38
|
"exports": {
|