@bolttech/form-engine-core 1.0.1-beta.2 → 1.0.1
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/index.esm.js +140 -85
- package/package.json +9 -9
- package/src/constants/constants.d.ts +2 -1
- package/src/formatters/string.d.ts +2 -2
- package/src/helpers/creditCard.d.ts +1 -1
- package/src/helpers/helpers.d.ts +2 -4
- package/src/index.d.ts +1 -0
- package/src/interfaces/schema.d.ts +28 -6
- package/src/managers/field.d.ts +0 -1
- package/src/managers/form.d.ts +9 -3
- package/src/managers/formGroup.d.ts +4 -2
- package/src/masks/generic.d.ts +1 -1
- package/src/masks/handler.d.ts +1 -1
- package/src/masks/string.d.ts +2 -0
- package/src/types/event.d.ts +75 -8
- package/src/types/mapper.d.ts +12 -20
- package/src/types/schema.d.ts +204 -37
- package/src/types/template.d.ts +21 -6
- package/src/validations/date.d.ts +1 -1
- package/src/validations/list.d.ts +1 -1
- package/src/validations/logical.d.ts +1 -1
- package/src/validations/string.d.ts +1 -1
- /package/{index.esm.d.ts → index.d.ts} +0 -0
package/index.esm.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged } from 'rxjs';
|
|
2
2
|
import creditCardType from 'credit-card-type';
|
|
3
|
-
import
|
|
3
|
+
import isNumber$1 from 'lodash/isNumber';
|
|
4
4
|
import { getCurrencySymbol } from '@gaignoux/currency';
|
|
5
|
+
import isFunction from 'lodash/isFunction';
|
|
6
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
7
|
+
import get from 'lodash/get';
|
|
8
|
+
import isEqual from 'lodash/isEqual';
|
|
9
|
+
import isNil from 'lodash/isNil';
|
|
10
|
+
import set from 'lodash/set';
|
|
5
11
|
|
|
6
12
|
var TMutationEnum;
|
|
7
13
|
(function (TMutationEnum) {
|
|
@@ -28,6 +34,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
28
34
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
29
35
|
PERFORMANCE OF THIS SOFTWARE.
|
|
30
36
|
***************************************************************************** */
|
|
37
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
38
|
+
|
|
31
39
|
|
|
32
40
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
33
41
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -404,7 +412,7 @@ const regex$1 = (value, formatters) => {
|
|
|
404
412
|
const getTypeCard = (value, availableOptions) => {
|
|
405
413
|
const rawValue = removeGaps(value === null || value === void 0 ? void 0 : value.toString());
|
|
406
414
|
const types = creditCardType(rawValue);
|
|
407
|
-
const selected =
|
|
415
|
+
const selected = typeof availableOptions === 'object' && availableOptions.length ? types === null || types === void 0 ? void 0 : types.filter(({
|
|
408
416
|
type: id1
|
|
409
417
|
}) => availableOptions.some(id2 => id2 === id1))[0] : types[0];
|
|
410
418
|
return [selected, rawValue];
|
|
@@ -673,12 +681,14 @@ const replaceAll = (value, masks) => {
|
|
|
673
681
|
*
|
|
674
682
|
* const formattedValue = currency(config.value, config.masks);
|
|
675
683
|
* console.log(formattedValue); // Output: '9.876,54 €'
|
|
684
|
+
*
|
|
685
|
+
* PS: To unCurrency this value, usage onlyFloatNumber formatter
|
|
676
686
|
* ```
|
|
677
687
|
*/
|
|
678
688
|
const currency = (value, masks) => {
|
|
679
689
|
if (!(masks === null || masks === void 0 ? void 0 : masks.currency)) return value;
|
|
680
690
|
const {
|
|
681
|
-
align = '
|
|
691
|
+
align = '',
|
|
682
692
|
decimal = '.',
|
|
683
693
|
precision = 2,
|
|
684
694
|
prefix = 'BBD',
|
|
@@ -702,6 +712,9 @@ const currency = (value, masks) => {
|
|
|
702
712
|
decimalPart = '0'.repeat(precision - decimalPart.length) + decimalPart;
|
|
703
713
|
newRawValue += decimal + decimalPart;
|
|
704
714
|
}
|
|
715
|
+
if (!align) {
|
|
716
|
+
return newRawValue;
|
|
717
|
+
}
|
|
705
718
|
const symbol = getCurrencySymbol(prefix);
|
|
706
719
|
return align === 'left' ? `${symbol} ${newRawValue}` : `${newRawValue} ${symbol}`;
|
|
707
720
|
};
|
|
@@ -1636,7 +1649,7 @@ const callback = (value, validations) => {
|
|
|
1636
1649
|
*/
|
|
1637
1650
|
const includes = (value, validations) => {
|
|
1638
1651
|
if (!value || !Array.isArray(validations === null || validations === void 0 ? void 0 : validations.includes)) return false;
|
|
1639
|
-
return !validations.includes.some(code => code === value || JSON.stringify(code) === value);
|
|
1652
|
+
return !(validations === null || validations === void 0 ? void 0 : validations.includes.some(code => code === value || JSON.stringify(code) === value));
|
|
1640
1653
|
};
|
|
1641
1654
|
|
|
1642
1655
|
/**
|
|
@@ -2521,7 +2534,6 @@ class FormField {
|
|
|
2521
2534
|
this.name = schemaComponent.name;
|
|
2522
2535
|
this.nameToSubmit = schemaComponent.nameToSubmit;
|
|
2523
2536
|
this.component = schemaComponent.component;
|
|
2524
|
-
this.path = path;
|
|
2525
2537
|
this.children = children;
|
|
2526
2538
|
this.validations = cloneDeep(schemaComponent.validations);
|
|
2527
2539
|
this.visibilityConditions = cloneDeep(schemaComponent.visibilityConditions);
|
|
@@ -2595,11 +2607,13 @@ class FormField {
|
|
|
2595
2607
|
if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
|
|
2596
2608
|
this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
|
|
2597
2609
|
}
|
|
2598
|
-
!this.apiEventQueueSubject$.observed
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
this.
|
|
2602
|
-
|
|
2610
|
+
if (!this.apiEventQueueSubject$.observed) {
|
|
2611
|
+
this.apiEventQueueSubject$.pipe(groupBy(({
|
|
2612
|
+
event
|
|
2613
|
+
}) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
|
|
2614
|
+
this.apiRequest(payload);
|
|
2615
|
+
});
|
|
2616
|
+
}
|
|
2603
2617
|
}
|
|
2604
2618
|
/**
|
|
2605
2619
|
* Retrieves the properties associated with the form field.
|
|
@@ -2704,7 +2718,9 @@ class FormField {
|
|
|
2704
2718
|
this.maskValue(this.formatValue(val));
|
|
2705
2719
|
this._metadata = val;
|
|
2706
2720
|
}
|
|
2707
|
-
|
|
2721
|
+
if (this.stateValue) {
|
|
2722
|
+
this.valueSubject$.next(this.stateValue);
|
|
2723
|
+
}
|
|
2708
2724
|
this.templateSubject$.next({
|
|
2709
2725
|
scope: 'fields',
|
|
2710
2726
|
key: this.name,
|
|
@@ -2758,9 +2774,11 @@ class FormField {
|
|
|
2758
2774
|
* if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
|
|
2759
2775
|
*/
|
|
2760
2776
|
triggerFieldValidNotification() {
|
|
2761
|
-
!this.fieldValidNotification$.closed
|
|
2762
|
-
|
|
2763
|
-
|
|
2777
|
+
if (!this.fieldValidNotification$.closed) {
|
|
2778
|
+
this.fieldValidNotification$.next({
|
|
2779
|
+
fieldTrigger: this.name
|
|
2780
|
+
});
|
|
2781
|
+
}
|
|
2764
2782
|
}
|
|
2765
2783
|
/**
|
|
2766
2784
|
* Retrieves the error messages associated with the form field.
|
|
@@ -2779,14 +2797,16 @@ class FormField {
|
|
|
2779
2797
|
var _a;
|
|
2780
2798
|
if (typeof errors === 'undefined' || isEqual(errors, this.errors)) return;
|
|
2781
2799
|
this._errors = errors;
|
|
2782
|
-
this.errorsList = Object.values(this.errors);
|
|
2800
|
+
this.errorsList = Object.values(this.errors).filter(el => el !== undefined && el !== null);
|
|
2783
2801
|
this.errorsString = this.errorsList.join(', ');
|
|
2784
2802
|
/**
|
|
2785
2803
|
* if any error receives a list of errors, set a prop for it, currently only supporting a single string
|
|
2786
2804
|
*/
|
|
2787
|
-
((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage)
|
|
2788
|
-
|
|
2789
|
-
|
|
2805
|
+
if ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) {
|
|
2806
|
+
this.errorSubject$.next({
|
|
2807
|
+
[this.mapper.events.setErrorMessage]: this.errorsString
|
|
2808
|
+
});
|
|
2809
|
+
}
|
|
2790
2810
|
this.templateSubject$.next({
|
|
2791
2811
|
scope: 'fields',
|
|
2792
2812
|
key: this.name,
|
|
@@ -2950,23 +2970,25 @@ class FormField {
|
|
|
2950
2970
|
let valid = true;
|
|
2951
2971
|
const errors = {};
|
|
2952
2972
|
const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
if (
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2973
|
+
if (schemaValidations) {
|
|
2974
|
+
Object.keys(schemaValidations).forEach(validationKey => {
|
|
2975
|
+
var _a;
|
|
2976
|
+
const error = handleValidation(this.value, schemaValidations, validations, validationKey);
|
|
2977
|
+
// setting valid flag
|
|
2978
|
+
valid = !error && valid;
|
|
2979
|
+
// setting error messages
|
|
2980
|
+
if (error && ((_a = this.validations) === null || _a === void 0 ? void 0 : _a.messages)) {
|
|
2981
|
+
if (validationKey in this.validations.messages) {
|
|
2982
|
+
const messages = this.validations.messages;
|
|
2983
|
+
errors[validationKey] = messages[validationKey];
|
|
2984
|
+
} else if ('default' in this.validations.messages) {
|
|
2985
|
+
errors[validationKey] = this.validations.messages.default;
|
|
2986
|
+
}
|
|
2987
|
+
} else {
|
|
2988
|
+
delete errors[validationKey];
|
|
2965
2989
|
}
|
|
2966
|
-
}
|
|
2967
|
-
|
|
2968
|
-
}
|
|
2969
|
-
});
|
|
2990
|
+
});
|
|
2991
|
+
}
|
|
2970
2992
|
this.valid = valid;
|
|
2971
2993
|
if ((_c = (_b = this.validations) === null || _b === void 0 ? void 0 : _b.eventMessages) === null || _c === void 0 ? void 0 : _c[event]) {
|
|
2972
2994
|
const eventMessages = {};
|
|
@@ -3011,10 +3033,12 @@ class FormField {
|
|
|
3011
3033
|
checkApiRequestValidations(config) {
|
|
3012
3034
|
let valid = true;
|
|
3013
3035
|
const preConditions = config.preConditions;
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3036
|
+
if (preConditions) {
|
|
3037
|
+
Object.keys(preConditions).forEach(validationKey => {
|
|
3038
|
+
const error = handleValidation(this.value, preConditions, validations, validationKey);
|
|
3039
|
+
valid = valid && !error;
|
|
3040
|
+
});
|
|
3041
|
+
}
|
|
3018
3042
|
if (config.blockRequestWhenInvalid) {
|
|
3019
3043
|
valid = valid && this.valid;
|
|
3020
3044
|
}
|
|
@@ -3026,20 +3050,20 @@ class FormField {
|
|
|
3026
3050
|
* @param {TEvents} event - The event type associated with the API request.
|
|
3027
3051
|
* @returns {Promise<void>}
|
|
3028
3052
|
*/
|
|
3029
|
-
apiRequest({
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3053
|
+
apiRequest(_a) {
|
|
3054
|
+
return __awaiter(this, arguments, void 0, function* ({
|
|
3055
|
+
event
|
|
3056
|
+
}) {
|
|
3057
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
3034
3058
|
let requestMadeOnce = false;
|
|
3035
3059
|
const configRequest = config => __awaiter(this, void 0, void 0, function* () {
|
|
3036
|
-
var
|
|
3060
|
+
var _a;
|
|
3037
3061
|
try {
|
|
3038
3062
|
const {
|
|
3039
3063
|
status,
|
|
3040
3064
|
response
|
|
3041
3065
|
} = yield makeRequest(config.method, config.url, config.headers, config.body, config.queryParams);
|
|
3042
|
-
const callbackTransform = (
|
|
3066
|
+
const callbackTransform = (_a = config.transform) === null || _a === void 0 ? void 0 : _a.callback;
|
|
3043
3067
|
const apiResponseData = callbackTransform ? callbackTransform({
|
|
3044
3068
|
payload: JSON.parse(String(response)),
|
|
3045
3069
|
formValues: this.getFormValues()
|
|
@@ -3057,7 +3081,7 @@ class FormField {
|
|
|
3057
3081
|
};
|
|
3058
3082
|
}
|
|
3059
3083
|
});
|
|
3060
|
-
if (this.api.apiState.lastEvent === 'ON_API_FIELD_RESPONSE' && event === 'ON_API_FIELD_RESPONSE' || !((
|
|
3084
|
+
if (this.api.apiState.lastEvent === 'ON_API_FIELD_RESPONSE' && event === 'ON_API_FIELD_RESPONSE' || !((_c = (_b = this.apiSchema) === null || _b === void 0 ? void 0 : _b.defaultConfig) === null || _c === void 0 ? void 0 : _c.events.includes(event)) && !(((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs) && Object.keys((_e = this.apiSchema) === null || _e === void 0 ? void 0 : _e.configs).some(key => {
|
|
3061
3085
|
var _a, _b;
|
|
3062
3086
|
return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
|
|
3063
3087
|
}))) return;
|
|
@@ -3066,9 +3090,11 @@ class FormField {
|
|
|
3066
3090
|
named: Object.assign({}, this.api.named),
|
|
3067
3091
|
apiState: Object.assign({}, this.api.apiState)
|
|
3068
3092
|
};
|
|
3069
|
-
const config = (
|
|
3070
|
-
if (config && ((
|
|
3071
|
-
!requestMadeOnce
|
|
3093
|
+
const config = (_f = this.apiSchema.defaultConfig) === null || _f === void 0 ? void 0 : _f.config;
|
|
3094
|
+
if (config && ((_h = (_g = this.apiSchema) === null || _g === void 0 ? void 0 : _g.defaultConfig) === null || _h === void 0 ? void 0 : _h.events.includes(event)) && this.checkApiRequestValidations(config)) {
|
|
3095
|
+
if (!requestMadeOnce) {
|
|
3096
|
+
this.notifyApiRequest();
|
|
3097
|
+
}
|
|
3072
3098
|
const {
|
|
3073
3099
|
response,
|
|
3074
3100
|
status
|
|
@@ -3079,7 +3105,7 @@ class FormField {
|
|
|
3079
3105
|
status
|
|
3080
3106
|
};
|
|
3081
3107
|
}
|
|
3082
|
-
if (((
|
|
3108
|
+
if (((_j = this.apiSchema) === null || _j === void 0 ? void 0 : _j.configs) && Object.keys((_k = this.apiSchema) === null || _k === void 0 ? void 0 : _k.configs).some(key => {
|
|
3083
3109
|
var _a, _b;
|
|
3084
3110
|
return (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[key].events.includes(event);
|
|
3085
3111
|
})) {
|
|
@@ -3088,10 +3114,12 @@ class FormField {
|
|
|
3088
3114
|
@TODO handle promises with error
|
|
3089
3115
|
*/
|
|
3090
3116
|
const result = yield Promise.all(Object.keys(this.apiSchema.configs).map(configKey => __awaiter(this, void 0, void 0, function* () {
|
|
3091
|
-
var
|
|
3092
|
-
const config = (
|
|
3093
|
-
if (config && ((
|
|
3094
|
-
!requestMadeOnce
|
|
3117
|
+
var _a, _b, _c, _d;
|
|
3118
|
+
const config = (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[configKey].config;
|
|
3119
|
+
if (config && ((_d = (_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) === null || _d === void 0 ? void 0 : _d[configKey].events.includes(event)) && this.checkApiRequestValidations(config)) {
|
|
3120
|
+
if (!requestMadeOnce) {
|
|
3121
|
+
this.notifyApiRequest();
|
|
3122
|
+
}
|
|
3095
3123
|
const {
|
|
3096
3124
|
response,
|
|
3097
3125
|
status
|
|
@@ -3132,12 +3160,12 @@ class FormField {
|
|
|
3132
3160
|
this.propsSubject$.unsubscribe();
|
|
3133
3161
|
this.errorSubject$.unsubscribe();
|
|
3134
3162
|
this.apiEventQueueSubject$.unsubscribe();
|
|
3135
|
-
this.dataSubject$.next({
|
|
3163
|
+
if (!this.dataSubject$.closed) this.dataSubject$.next({
|
|
3136
3164
|
event: 'ON_FIELD_UNMOUNT',
|
|
3137
3165
|
fieldIndex: this.name,
|
|
3138
3166
|
formIndex: this.formIndex
|
|
3139
3167
|
});
|
|
3140
|
-
!this.fieldEventSubject$.closed
|
|
3168
|
+
if (!this.fieldEventSubject$.closed) this.fieldEventSubject$.next({
|
|
3141
3169
|
event: 'ON_FIELD_UNMOUNT',
|
|
3142
3170
|
fieldName: this.name,
|
|
3143
3171
|
fieldInstance: this
|
|
@@ -3198,6 +3226,8 @@ class FormCore {
|
|
|
3198
3226
|
this.queuedFieldResetPropertyEvents = new Map();
|
|
3199
3227
|
this.queuedInitialValues = new Map();
|
|
3200
3228
|
this._valid = false;
|
|
3229
|
+
this.stopEventsOnSubmit = false;
|
|
3230
|
+
this.submitted = false;
|
|
3201
3231
|
this.index = entry.index;
|
|
3202
3232
|
this.schema = entry.schema;
|
|
3203
3233
|
this.fields = new Map();
|
|
@@ -3212,7 +3242,9 @@ class FormCore {
|
|
|
3212
3242
|
this.mappers.set(mapper.componentName, mapper);
|
|
3213
3243
|
});
|
|
3214
3244
|
if ((!entry.submitSubject$ || !entry.dataSubject$ || !entry.formValidSubject$) && this.config.defaultLogVerbose) console.warn(`some formGroup events are not properly instanciated, any onData, onValid, onSubmit events managed by formGroup won't trigger on form: ${this.index}`);
|
|
3215
|
-
|
|
3245
|
+
if (this.schema) {
|
|
3246
|
+
FormCore.checkIndexes(this.schema.components);
|
|
3247
|
+
}
|
|
3216
3248
|
this.templateSubject$ = new Subject();
|
|
3217
3249
|
this.fieldEventSubject$ = new Subject();
|
|
3218
3250
|
this.mountSubject$ = new Subject();
|
|
@@ -3228,12 +3260,16 @@ class FormCore {
|
|
|
3228
3260
|
this.mountSubject$.subscribe(this.mountActions.bind(this));
|
|
3229
3261
|
this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
|
|
3230
3262
|
this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
|
|
3263
|
+
this.stopEventsOnSubmit = (entry === null || entry === void 0 ? void 0 : entry.stopEventsOnSubmit) || false;
|
|
3264
|
+
this.submitted = false;
|
|
3231
3265
|
}
|
|
3232
3266
|
/**
|
|
3233
3267
|
* mock function to simulate form mount onto the adapter
|
|
3234
3268
|
*/
|
|
3235
3269
|
generateFields() {
|
|
3236
|
-
|
|
3270
|
+
if (this.schema) {
|
|
3271
|
+
this.serializeStructure(this.schema.components);
|
|
3272
|
+
}
|
|
3237
3273
|
this.fields.forEach(field => {
|
|
3238
3274
|
field.mountField({
|
|
3239
3275
|
valueSubscription: () => null,
|
|
@@ -3241,6 +3277,13 @@ class FormCore {
|
|
|
3241
3277
|
});
|
|
3242
3278
|
});
|
|
3243
3279
|
}
|
|
3280
|
+
/**
|
|
3281
|
+
*flag utility to prevent Subjects from emitting after form submission and stopEventsOnSubmit
|
|
3282
|
+
* @returns {boolean} - result of the flag utility.
|
|
3283
|
+
*/
|
|
3284
|
+
submitChecker() {
|
|
3285
|
+
return !(this.stopEventsOnSubmit && this.submitted);
|
|
3286
|
+
}
|
|
3244
3287
|
/**
|
|
3245
3288
|
* callback function passed to field instance to notify field adapter mount status
|
|
3246
3289
|
* once the field has all field instance properties set, this function will handle all
|
|
@@ -3260,7 +3303,7 @@ class FormCore {
|
|
|
3260
3303
|
@TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
|
|
3261
3304
|
since they are dependent on adapter field recycling runtimes
|
|
3262
3305
|
*/
|
|
3263
|
-
this.config.defaultLogVerbose
|
|
3306
|
+
if (this.config.defaultLogVerbose) console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
|
|
3264
3307
|
return;
|
|
3265
3308
|
}
|
|
3266
3309
|
this.subscribeTemplates();
|
|
@@ -3272,12 +3315,16 @@ class FormCore {
|
|
|
3272
3315
|
scope: 'iVars',
|
|
3273
3316
|
event: 'ON_IVARS'
|
|
3274
3317
|
});
|
|
3275
|
-
if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
}
|
|
3318
|
+
if (!this.queuedInitialValues.has(key)) if (field.valuePropName && !field.value) {
|
|
3319
|
+
field.emitValue({
|
|
3320
|
+
event: 'ON_FIELD_MOUNT',
|
|
3321
|
+
value: ''
|
|
3322
|
+
});
|
|
3323
|
+
} else {
|
|
3324
|
+
field.emitEvents({
|
|
3325
|
+
event: 'ON_FIELD_MOUNT'
|
|
3326
|
+
});
|
|
3327
|
+
}
|
|
3281
3328
|
this.checkFieldEventQueues(key);
|
|
3282
3329
|
}
|
|
3283
3330
|
}
|
|
@@ -3434,7 +3481,7 @@ class FormCore {
|
|
|
3434
3481
|
}) {
|
|
3435
3482
|
const field = this.fields.get(key);
|
|
3436
3483
|
if (!field) {
|
|
3437
|
-
this.config.defaultLogVerbose
|
|
3484
|
+
if (this.config.defaultLogVerbose) console.warn(`failed to update field ${key}`);
|
|
3438
3485
|
return;
|
|
3439
3486
|
}
|
|
3440
3487
|
if (path.length > 0) {
|
|
@@ -3456,7 +3503,7 @@ class FormCore {
|
|
|
3456
3503
|
if (Array.isArray(fieldProp) || typeof fieldProp === 'object' && !isNil(fieldProp)) {
|
|
3457
3504
|
propState = cloneDeep(fieldProp);
|
|
3458
3505
|
} else {
|
|
3459
|
-
this.config.defaultLogVerbose
|
|
3506
|
+
if (this.config.defaultLogVerbose) console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
|
|
3460
3507
|
return;
|
|
3461
3508
|
}
|
|
3462
3509
|
set(propState, path, value);
|
|
@@ -3547,8 +3594,10 @@ class FormCore {
|
|
|
3547
3594
|
try {
|
|
3548
3595
|
return parse ? new Function(`return ${value}`)() : value;
|
|
3549
3596
|
} catch (_a) {
|
|
3550
|
-
this.config.defaultLogVerbose
|
|
3551
|
-
|
|
3597
|
+
if (this.config.defaultLogVerbose) {
|
|
3598
|
+
console.warn(`unhandled parsing on ${expression} returning`);
|
|
3599
|
+
console.warn(value);
|
|
3600
|
+
}
|
|
3552
3601
|
return value;
|
|
3553
3602
|
}
|
|
3554
3603
|
});
|
|
@@ -3699,6 +3748,9 @@ class FormCore {
|
|
|
3699
3748
|
});
|
|
3700
3749
|
}
|
|
3701
3750
|
} else {
|
|
3751
|
+
fieldInstance.emitEvents({
|
|
3752
|
+
event: 'ON_FIELD_UNMOUNT'
|
|
3753
|
+
});
|
|
3702
3754
|
if (fieldInstance.persistValue) {
|
|
3703
3755
|
this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
|
|
3704
3756
|
}
|
|
@@ -3965,7 +4017,6 @@ class FormCore {
|
|
|
3965
4017
|
});
|
|
3966
4018
|
} else {
|
|
3967
4019
|
currField.children = ((_a = structElement === null || structElement === void 0 ? void 0 : structElement.children) === null || _a === void 0 ? void 0 : _a.map(el => el.name)) || (currField === null || currField === void 0 ? void 0 : currField.children) || [];
|
|
3968
|
-
currField.path = path;
|
|
3969
4020
|
currField.originalSchema = structElement;
|
|
3970
4021
|
currField.templateSubject$ = this.templateSubject$;
|
|
3971
4022
|
}
|
|
@@ -4062,7 +4113,7 @@ class FormCore {
|
|
|
4062
4113
|
subscribeFieldEvent({
|
|
4063
4114
|
callback
|
|
4064
4115
|
}) {
|
|
4065
|
-
const sub = this.fieldEventSubject$.pipe(groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
|
|
4116
|
+
const sub = this.fieldEventSubject$.pipe(filter(() => this.submitChecker()), groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
|
|
4066
4117
|
next: callback
|
|
4067
4118
|
});
|
|
4068
4119
|
return sub;
|
|
@@ -4086,7 +4137,7 @@ class FormCore {
|
|
|
4086
4137
|
subscribeData(callback) {
|
|
4087
4138
|
const sub = this.dataSubject$.pipe(filter(({
|
|
4088
4139
|
formIndex
|
|
4089
|
-
}) => this.index === formIndex), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4140
|
+
}) => this.index === formIndex && this.submitChecker()), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4090
4141
|
fieldIndex
|
|
4091
4142
|
}) => ({
|
|
4092
4143
|
field: fieldIndex,
|
|
@@ -4104,7 +4155,7 @@ class FormCore {
|
|
|
4104
4155
|
subscribeOnSubmit(callback) {
|
|
4105
4156
|
const sub = this.submitSubject$.pipe(filter(({
|
|
4106
4157
|
formIndex
|
|
4107
|
-
}) => formIndex === this.index), map(({
|
|
4158
|
+
}) => formIndex === this.index && this.submitChecker()), map(({
|
|
4108
4159
|
values
|
|
4109
4160
|
}) => values)).subscribe({
|
|
4110
4161
|
next: callback
|
|
@@ -4119,7 +4170,7 @@ class FormCore {
|
|
|
4119
4170
|
subscribeFormValidation(callback) {
|
|
4120
4171
|
const sub = this.formValidSubject$.pipe(filter(({
|
|
4121
4172
|
formIndex
|
|
4122
|
-
}) => this.index === formIndex),
|
|
4173
|
+
}) => this.index === formIndex), map(() => ({
|
|
4123
4174
|
formIndex: this.index,
|
|
4124
4175
|
valid: this.valid
|
|
4125
4176
|
})), distinctUntilKeyChanged('valid'), startWith({
|
|
@@ -4145,6 +4196,7 @@ class FormCore {
|
|
|
4145
4196
|
formIndex: this.index,
|
|
4146
4197
|
values
|
|
4147
4198
|
});
|
|
4199
|
+
this.submitted = true;
|
|
4148
4200
|
}
|
|
4149
4201
|
/**
|
|
4150
4202
|
* recycles all the Suscriptions, to be called from the adapter when the form leaves the page
|
|
@@ -4208,6 +4260,7 @@ class FormGroup {
|
|
|
4208
4260
|
this.dataSubject$ = new Subject();
|
|
4209
4261
|
this.formValidSubject$ = new Subject();
|
|
4210
4262
|
this.submitSubject$ = new Subject();
|
|
4263
|
+
this.mappers = entry === null || entry === void 0 ? void 0 : entry.mappers;
|
|
4211
4264
|
}
|
|
4212
4265
|
/**
|
|
4213
4266
|
* Creates an empty form with given index
|
|
@@ -4333,17 +4386,20 @@ class FormGroup {
|
|
|
4333
4386
|
var _a, _b;
|
|
4334
4387
|
(_a = this.forms.get(index)) === null || _a === void 0 ? void 0 : _a.submit();
|
|
4335
4388
|
const res = (_b = this.forms.get(index)) === null || _b === void 0 ? void 0 : _b.getFormValues();
|
|
4389
|
+
const formMetadata = typeof (res === null || res === void 0 ? void 0 : res.metadata) === 'object' && res.metadata !== null ? res.metadata : {};
|
|
4336
4390
|
isValid = isValid && ((res === null || res === void 0 ? void 0 : res.isValid) || false);
|
|
4337
4391
|
values = Object.assign(Object.assign({}, values), (res === null || res === void 0 ? void 0 : res.values) || {});
|
|
4338
|
-
metadata = Object.assign(Object.assign({}, metadata),
|
|
4392
|
+
metadata = Object.assign(Object.assign({}, metadata), formMetadata);
|
|
4339
4393
|
erroredFields = [...erroredFields, ...((res === null || res === void 0 ? void 0 : res.erroredFields) || [])];
|
|
4340
4394
|
});
|
|
4341
|
-
isValid && callback
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4395
|
+
if (isValid && callback) {
|
|
4396
|
+
callback({
|
|
4397
|
+
erroredFields,
|
|
4398
|
+
isValid,
|
|
4399
|
+
values,
|
|
4400
|
+
metadata
|
|
4401
|
+
});
|
|
4402
|
+
}
|
|
4347
4403
|
}
|
|
4348
4404
|
onDataSubscription({
|
|
4349
4405
|
ids,
|
|
@@ -4353,9 +4409,8 @@ class FormGroup {
|
|
|
4353
4409
|
formIndex
|
|
4354
4410
|
}) => ids.includes(formIndex)), groupBy(({
|
|
4355
4411
|
event,
|
|
4356
|
-
formIndex
|
|
4357
|
-
|
|
4358
|
-
}) => `${event}.${formIndex}.${fieldIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4412
|
+
formIndex
|
|
4413
|
+
}) => `${event}.${formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
|
|
4359
4414
|
fieldIndex,
|
|
4360
4415
|
formIndex
|
|
4361
4416
|
}) => ids.reduce((acc, curr) => {
|
|
@@ -4379,7 +4434,7 @@ class FormGroup {
|
|
|
4379
4434
|
formIndex
|
|
4380
4435
|
}) => ids.includes(formIndex)), groupBy(({
|
|
4381
4436
|
formIndex
|
|
4382
|
-
}) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(
|
|
4437
|
+
}) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(0))), startWith({
|
|
4383
4438
|
fieldTrigger: null
|
|
4384
4439
|
}), map(() => ({
|
|
4385
4440
|
groupValid: ids.every(id => {
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bolttech/form-engine-core",
|
|
3
|
-
"version": "1.0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"@gaignoux/currency": "^1.1.0",
|
|
6
|
+
"credit-card-type": "^10.0.0",
|
|
7
|
+
"lodash": "^4.17.21",
|
|
8
|
+
"rxjs": "^7.8.1"
|
|
9
|
+
},
|
|
4
10
|
"module": "./index.esm.js",
|
|
5
11
|
"type": "module",
|
|
6
12
|
"main": "./index.esm.js",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
"credit-card-type": "10.0.1",
|
|
10
|
-
"lodash": "4.17.21",
|
|
11
|
-
"rxjs": "7.8.1"
|
|
12
|
-
},
|
|
13
|
-
"peerDependencies": {}
|
|
14
|
-
}
|
|
13
|
+
"types": "./index.d.ts"
|
|
14
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IFormField } from "../managers/field";
|
|
1
2
|
declare const DEFAULT_API_DEBOUNCE_TIME = 1000;
|
|
2
3
|
declare const DEFAULT_STATE_REFRESH_TIME = 100;
|
|
3
4
|
declare const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR: RegExp;
|
|
@@ -5,6 +6,6 @@ declare const TEMPLATE_REGEX_DELIMITATOR: RegExp;
|
|
|
5
6
|
declare const TEMPLATE_REGEX_OPERATOR_SPLITTER: RegExp;
|
|
6
7
|
declare const TEMPLATE_REGEX_OPERATOR_MATCHER: RegExp;
|
|
7
8
|
declare const TEMPLATE_AVALIABLE_SCOPES: readonly ["fields", "iVars", "form"];
|
|
8
|
-
declare const ALLOWED_RESET_PROPS_MUTATIONS: ("api" | "apiSchema" | "props" | "validations" | "visibilityConditions" | "resetValues")[];
|
|
9
|
+
declare const ALLOWED_RESET_PROPS_MUTATIONS: (keyof Pick<IFormField, "api" | "apiSchema" | "props" | "validations" | "visibilityConditions" | "resetValues">)[];
|
|
9
10
|
declare const DEFAULT_LOG_VERBOSE = false;
|
|
10
11
|
export { DEFAULT_API_DEBOUNCE_TIME, DEFAULT_STATE_REFRESH_TIME, DEFAULT_LOG_VERBOSE, TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR, TEMPLATE_REGEX_DELIMITATOR, TEMPLATE_REGEX_OPERATOR_SPLITTER, TEMPLATE_REGEX_OPERATOR_MATCHER, TEMPLATE_AVALIABLE_SCOPES, ALLOWED_RESET_PROPS_MUTATIONS, };
|
|
@@ -60,7 +60,7 @@ export declare const onlyFloatNumber: (value: unknown, formatters: TFormatters)
|
|
|
60
60
|
* console.log(trimmedValue); // Output: 'hello world'
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
|
-
export declare const trim: (value: unknown, formatters
|
|
63
|
+
export declare const trim: (value: unknown, formatters?: TFormatters) => unknown;
|
|
64
64
|
/**
|
|
65
65
|
* Truncates the input value to a specified maximum length if necessary.
|
|
66
66
|
*
|
|
@@ -85,4 +85,4 @@ export declare const trim: (value: unknown, formatters: TFormatters) => unknown;
|
|
|
85
85
|
* console.log(result); // "Short" (no truncation since input is shorter than maxLength)
|
|
86
86
|
* ```
|
|
87
87
|
*/
|
|
88
|
-
export declare const maxLength: (value: string | number, formatters: TFormatters) => string | number;
|
|
88
|
+
export declare const maxLength: (value: string | number | null | undefined, formatters: TFormatters) => string | number | null | undefined;
|
|
@@ -67,7 +67,7 @@ export type TGetTypeCard = [ICreditCardType, string];
|
|
|
67
67
|
* console.log(rawValue); // Output: '4111111111111111'
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
|
-
export declare const getTypeCard: (value: string, availableOptions?: string[]) => TGetTypeCard;
|
|
70
|
+
export declare const getTypeCard: (value: string, availableOptions?: string[] | boolean) => TGetTypeCard;
|
|
71
71
|
/**
|
|
72
72
|
* Formats a credit card number according to its type's gaps and lengths.
|
|
73
73
|
*
|
package/src/helpers/helpers.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
|
|
3
1
|
import { TApiResponsePayload } from '../types/schema';
|
|
4
|
-
import { TSubscribedTemplates } from '../types/template';
|
|
2
|
+
import { TSubscribedTemplates, TTemplateAvaliableScopes } from '../types/template';
|
|
5
3
|
import { OutgoingHttpHeaders } from 'http2';
|
|
6
4
|
/**
|
|
7
5
|
* Makes an HTTP request using XMLHttpRequest.
|
|
@@ -34,7 +32,7 @@ declare function makeRequest(method: string, url: string, headers?: OutgoingHttp
|
|
|
34
32
|
* ```
|
|
35
33
|
*/
|
|
36
34
|
declare function extractFieldKeys(expression: string): {
|
|
37
|
-
originScopeKeys:
|
|
35
|
+
originScopeKeys: TTemplateAvaliableScopes[];
|
|
38
36
|
originFieldKeys: string[];
|
|
39
37
|
originPropertyKeys: string[];
|
|
40
38
|
};
|
package/src/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './types/form';
|
|
|
3
3
|
export * from './types/schema';
|
|
4
4
|
export * from './types/template';
|
|
5
5
|
export * from './types/mapper';
|
|
6
|
+
export * from './types/utility';
|
|
6
7
|
export * from './interfaces/schema';
|
|
7
8
|
export * from './interfaces/state';
|
|
8
9
|
export * from './managers/form';
|