@bolttech/form-engine-core 1.0.2-beta.1 → 1.0.2

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.
Files changed (46) hide show
  1. package/index.d.ts +2314 -0
  2. package/index.esm.js +131 -81
  3. package/package.json +9 -10
  4. package/index.esm.d.ts +0 -1
  5. package/src/constants/constants.d.ts +0 -10
  6. package/src/formatters/creditCard.d.ts +0 -23
  7. package/src/formatters/custom.d.ts +0 -29
  8. package/src/formatters/handler.d.ts +0 -2
  9. package/src/formatters/regex.d.ts +0 -47
  10. package/src/formatters/splitter.d.ts +0 -17
  11. package/src/formatters/string.d.ts +0 -88
  12. package/src/helpers/SafeSubject.d.ts +0 -11
  13. package/src/helpers/creditCard.d.ts +0 -95
  14. package/src/helpers/helpers.d.ts +0 -67
  15. package/src/helpers/validation.d.ts +0 -27
  16. package/src/index.d.ts +0 -10
  17. package/src/interfaces/schema.d.ts +0 -112
  18. package/src/interfaces/state.d.ts +0 -22
  19. package/src/managers/field.d.ts +0 -326
  20. package/src/managers/form.d.ts +0 -346
  21. package/src/managers/formGroup.d.ts +0 -110
  22. package/src/managers/index.d.ts +0 -3
  23. package/src/masks/creditCard.d.ts +0 -60
  24. package/src/masks/generic.d.ts +0 -39
  25. package/src/masks/handler.d.ts +0 -2
  26. package/src/masks/string.d.ts +0 -99
  27. package/src/types/event.d.ts +0 -109
  28. package/src/types/form.d.ts +0 -55
  29. package/src/types/mapper.d.ts +0 -95
  30. package/src/types/schema.d.ts +0 -835
  31. package/src/types/template.d.ts +0 -50
  32. package/src/types/utility.d.ts +0 -6
  33. package/src/validations/creditCard.d.ts +0 -52
  34. package/src/validations/custom.d.ts +0 -25
  35. package/src/validations/date.d.ts +0 -79
  36. package/src/validations/document.d.ts +0 -25
  37. package/src/validations/handler.d.ts +0 -2
  38. package/src/validations/length.d.ts +0 -39
  39. package/src/validations/list.d.ts +0 -32
  40. package/src/validations/logical.d.ts +0 -75
  41. package/src/validations/multiple.d.ts +0 -31
  42. package/src/validations/namedRule.d.ts +0 -22
  43. package/src/validations/number.d.ts +0 -145
  44. package/src/validations/object.d.ts +0 -44
  45. package/src/validations/regex.d.ts +0 -217
  46. package/src/validations/string.d.ts +0 -53
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 { isNumber as isNumber$1, isFunction, cloneDeep, isEqual, get, isNil, set } from 'lodash';
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 = (availableOptions === null || availableOptions === void 0 ? void 0 : availableOptions.length) ? types === null || types === void 0 ? void 0 : types.filter(({
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];
@@ -1641,7 +1649,7 @@ const callback = (value, validations) => {
1641
1649
  */
1642
1650
  const includes = (value, validations) => {
1643
1651
  if (!value || !Array.isArray(validations === null || validations === void 0 ? void 0 : validations.includes)) return false;
1644
- 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));
1645
1653
  };
1646
1654
 
1647
1655
  /**
@@ -2526,7 +2534,6 @@ class FormField {
2526
2534
  this.name = schemaComponent.name;
2527
2535
  this.nameToSubmit = schemaComponent.nameToSubmit;
2528
2536
  this.component = schemaComponent.component;
2529
- this.path = path;
2530
2537
  this.children = children;
2531
2538
  this.validations = cloneDeep(schemaComponent.validations);
2532
2539
  this.visibilityConditions = cloneDeep(schemaComponent.visibilityConditions);
@@ -2600,11 +2607,13 @@ class FormField {
2600
2607
  if (!this.apiEventQueueSubject$ || this.apiEventQueueSubject$.closed) {
2601
2608
  this.apiEventQueueSubject$ = new SafeSubject(() => this.mounted);
2602
2609
  }
2603
- !this.apiEventQueueSubject$.observed && this.apiEventQueueSubject$.pipe(groupBy(({
2604
- event
2605
- }) => event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultAPIdebounceTimeMS))), filter(() => this.apiEventQueueSubject$ && !this.apiEventQueueSubject$.closed)).subscribe(payload => {
2606
- this.apiRequest(payload);
2607
- });
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
+ }
2608
2617
  }
2609
2618
  /**
2610
2619
  * Retrieves the properties associated with the form field.
@@ -2709,7 +2718,9 @@ class FormField {
2709
2718
  this.maskValue(this.formatValue(val));
2710
2719
  this._metadata = val;
2711
2720
  }
2712
- this.stateValue && this.valueSubject$.next(this.stateValue);
2721
+ if (this.stateValue) {
2722
+ this.valueSubject$.next(this.stateValue);
2723
+ }
2713
2724
  this.templateSubject$.next({
2714
2725
  scope: 'fields',
2715
2726
  key: this.name,
@@ -2763,9 +2774,11 @@ class FormField {
2763
2774
  * if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
2764
2775
  */
2765
2776
  triggerFieldValidNotification() {
2766
- !this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
2767
- fieldTrigger: this.name
2768
- });
2777
+ if (!this.fieldValidNotification$.closed) {
2778
+ this.fieldValidNotification$.next({
2779
+ fieldTrigger: this.name
2780
+ });
2781
+ }
2769
2782
  }
2770
2783
  /**
2771
2784
  * Retrieves the error messages associated with the form field.
@@ -2784,14 +2797,16 @@ class FormField {
2784
2797
  var _a;
2785
2798
  if (typeof errors === 'undefined' || isEqual(errors, this.errors)) return;
2786
2799
  this._errors = errors;
2787
- this.errorsList = Object.values(this.errors);
2800
+ this.errorsList = Object.values(this.errors).filter(el => el !== undefined && el !== null);
2788
2801
  this.errorsString = this.errorsList.join(', ');
2789
2802
  /**
2790
2803
  * if any error receives a list of errors, set a prop for it, currently only supporting a single string
2791
2804
  */
2792
- ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && this.errorSubject$.next({
2793
- [this.mapper.events.setErrorMessage]: this.errorsString
2794
- });
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
+ }
2795
2810
  this.templateSubject$.next({
2796
2811
  scope: 'fields',
2797
2812
  key: this.name,
@@ -2955,23 +2970,25 @@ class FormField {
2955
2970
  let valid = true;
2956
2971
  const errors = {};
2957
2972
  const schemaValidations = (_a = this.validations) === null || _a === void 0 ? void 0 : _a.methods;
2958
- schemaValidations && Object.keys(schemaValidations).forEach(validationKey => {
2959
- var _a;
2960
- const error = handleValidation(this.value, schemaValidations, validations, validationKey);
2961
- // setting valid flag
2962
- valid = !error && valid;
2963
- // setting error messages
2964
- if (error && ((_a = this.validations) === null || _a === void 0 ? void 0 : _a.messages)) {
2965
- if (validationKey in this.validations.messages) {
2966
- const messages = this.validations.messages;
2967
- errors[validationKey] = messages[validationKey];
2968
- } else if ('default' in this.validations.messages) {
2969
- errors[validationKey] = this.validations.messages.default;
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];
2970
2989
  }
2971
- } else {
2972
- delete errors[validationKey];
2973
- }
2974
- });
2990
+ });
2991
+ }
2975
2992
  this.valid = valid;
2976
2993
  if ((_c = (_b = this.validations) === null || _b === void 0 ? void 0 : _b.eventMessages) === null || _c === void 0 ? void 0 : _c[event]) {
2977
2994
  const eventMessages = {};
@@ -3016,10 +3033,12 @@ class FormField {
3016
3033
  checkApiRequestValidations(config) {
3017
3034
  let valid = true;
3018
3035
  const preConditions = config.preConditions;
3019
- preConditions && Object.keys(preConditions).forEach(validationKey => {
3020
- const error = handleValidation(this.value, preConditions, validations, validationKey);
3021
- valid = valid && !error;
3022
- });
3036
+ if (preConditions) {
3037
+ Object.keys(preConditions).forEach(validationKey => {
3038
+ const error = handleValidation(this.value, preConditions, validations, validationKey);
3039
+ valid = valid && !error;
3040
+ });
3041
+ }
3023
3042
  if (config.blockRequestWhenInvalid) {
3024
3043
  valid = valid && this.valid;
3025
3044
  }
@@ -3031,20 +3050,20 @@ class FormField {
3031
3050
  * @param {TEvents} event - The event type associated with the API request.
3032
3051
  * @returns {Promise<void>}
3033
3052
  */
3034
- apiRequest({
3035
- event
3036
- }) {
3037
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3038
- return __awaiter(this, void 0, void 0, function* () {
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;
3039
3058
  let requestMadeOnce = false;
3040
3059
  const configRequest = config => __awaiter(this, void 0, void 0, function* () {
3041
- var _k;
3060
+ var _a;
3042
3061
  try {
3043
3062
  const {
3044
3063
  status,
3045
3064
  response
3046
3065
  } = yield makeRequest(config.method, config.url, config.headers, config.body, config.queryParams);
3047
- const callbackTransform = (_k = config.transform) === null || _k === void 0 ? void 0 : _k.callback;
3066
+ const callbackTransform = (_a = config.transform) === null || _a === void 0 ? void 0 : _a.callback;
3048
3067
  const apiResponseData = callbackTransform ? callbackTransform({
3049
3068
  payload: JSON.parse(String(response)),
3050
3069
  formValues: this.getFormValues()
@@ -3062,7 +3081,7 @@ class FormField {
3062
3081
  };
3063
3082
  }
3064
3083
  });
3065
- if (this.api.apiState.lastEvent === 'ON_API_FIELD_RESPONSE' && event === 'ON_API_FIELD_RESPONSE' || !((_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.defaultConfig) === null || _b === void 0 ? void 0 : _b.events.includes(event)) && !(((_c = this.apiSchema) === null || _c === void 0 ? void 0 : _c.configs) && Object.keys((_d = this.apiSchema) === null || _d === void 0 ? void 0 : _d.configs).some(key => {
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 => {
3066
3085
  var _a, _b;
3067
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);
3068
3087
  }))) return;
@@ -3071,9 +3090,11 @@ class FormField {
3071
3090
  named: Object.assign({}, this.api.named),
3072
3091
  apiState: Object.assign({}, this.api.apiState)
3073
3092
  };
3074
- const config = (_e = this.apiSchema.defaultConfig) === null || _e === void 0 ? void 0 : _e.config;
3075
- if (config && ((_g = (_f = this.apiSchema) === null || _f === void 0 ? void 0 : _f.defaultConfig) === null || _g === void 0 ? void 0 : _g.events.includes(event)) && this.checkApiRequestValidations(config)) {
3076
- !requestMadeOnce && this.notifyApiRequest();
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
+ }
3077
3098
  const {
3078
3099
  response,
3079
3100
  status
@@ -3084,7 +3105,7 @@ class FormField {
3084
3105
  status
3085
3106
  };
3086
3107
  }
3087
- if (((_h = this.apiSchema) === null || _h === void 0 ? void 0 : _h.configs) && Object.keys((_j = this.apiSchema) === null || _j === void 0 ? void 0 : _j.configs).some(key => {
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 => {
3088
3109
  var _a, _b;
3089
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);
3090
3111
  })) {
@@ -3093,10 +3114,12 @@ class FormField {
3093
3114
  @TODO handle promises with error
3094
3115
  */
3095
3116
  const result = yield Promise.all(Object.keys(this.apiSchema.configs).map(configKey => __awaiter(this, void 0, void 0, function* () {
3096
- var _l, _m, _o, _p;
3097
- const config = (_m = (_l = this.apiSchema) === null || _l === void 0 ? void 0 : _l.configs) === null || _m === void 0 ? void 0 : _m[configKey].config;
3098
- if (config && ((_p = (_o = this.apiSchema) === null || _o === void 0 ? void 0 : _o.configs) === null || _p === void 0 ? void 0 : _p[configKey].events.includes(event)) && this.checkApiRequestValidations(config)) {
3099
- !requestMadeOnce && this.notifyApiRequest();
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
+ }
3100
3123
  const {
3101
3124
  response,
3102
3125
  status
@@ -3137,12 +3160,12 @@ class FormField {
3137
3160
  this.propsSubject$.unsubscribe();
3138
3161
  this.errorSubject$.unsubscribe();
3139
3162
  this.apiEventQueueSubject$.unsubscribe();
3140
- this.dataSubject$.next({
3163
+ if (!this.dataSubject$.closed) this.dataSubject$.next({
3141
3164
  event: 'ON_FIELD_UNMOUNT',
3142
3165
  fieldIndex: this.name,
3143
3166
  formIndex: this.formIndex
3144
3167
  });
3145
- !this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
3168
+ if (!this.fieldEventSubject$.closed) this.fieldEventSubject$.next({
3146
3169
  event: 'ON_FIELD_UNMOUNT',
3147
3170
  fieldName: this.name,
3148
3171
  fieldInstance: this
@@ -3203,6 +3226,8 @@ class FormCore {
3203
3226
  this.queuedFieldResetPropertyEvents = new Map();
3204
3227
  this.queuedInitialValues = new Map();
3205
3228
  this._valid = false;
3229
+ this.stopEventsOnSubmit = false;
3230
+ this.submitted = false;
3206
3231
  this.index = entry.index;
3207
3232
  this.schema = entry.schema;
3208
3233
  this.fields = new Map();
@@ -3217,7 +3242,9 @@ class FormCore {
3217
3242
  this.mappers.set(mapper.componentName, mapper);
3218
3243
  });
3219
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}`);
3220
- this.schema && FormCore.checkIndexes(this.schema.components);
3245
+ if (this.schema) {
3246
+ FormCore.checkIndexes(this.schema.components);
3247
+ }
3221
3248
  this.templateSubject$ = new Subject();
3222
3249
  this.fieldEventSubject$ = new Subject();
3223
3250
  this.mountSubject$ = new Subject();
@@ -3233,12 +3260,16 @@ class FormCore {
3233
3260
  this.mountSubject$.subscribe(this.mountActions.bind(this));
3234
3261
  this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
3235
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;
3236
3265
  }
3237
3266
  /**
3238
3267
  * mock function to simulate form mount onto the adapter
3239
3268
  */
3240
3269
  generateFields() {
3241
- this.schema && this.serializeStructure(this.schema.components);
3270
+ if (this.schema) {
3271
+ this.serializeStructure(this.schema.components);
3272
+ }
3242
3273
  this.fields.forEach(field => {
3243
3274
  field.mountField({
3244
3275
  valueSubscription: () => null,
@@ -3246,6 +3277,13 @@ class FormCore {
3246
3277
  });
3247
3278
  });
3248
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
+ }
3249
3287
  /**
3250
3288
  * callback function passed to field instance to notify field adapter mount status
3251
3289
  * once the field has all field instance properties set, this function will handle all
@@ -3265,7 +3303,7 @@ class FormCore {
3265
3303
  @TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
3266
3304
  since they are dependent on adapter field recycling runtimes
3267
3305
  */
3268
- this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
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`);
3269
3307
  return;
3270
3308
  }
3271
3309
  this.subscribeTemplates();
@@ -3277,12 +3315,16 @@ class FormCore {
3277
3315
  scope: 'iVars',
3278
3316
  event: 'ON_IVARS'
3279
3317
  });
3280
- if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
3281
- event: 'ON_FIELD_MOUNT',
3282
- value: ''
3283
- }) : field.emitEvents({
3284
- event: 'ON_FIELD_MOUNT'
3285
- });
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
+ }
3286
3328
  this.checkFieldEventQueues(key);
3287
3329
  }
3288
3330
  }
@@ -3439,7 +3481,7 @@ class FormCore {
3439
3481
  }) {
3440
3482
  const field = this.fields.get(key);
3441
3483
  if (!field) {
3442
- this.config.defaultLogVerbose && console.warn(`failed to update field ${key}`);
3484
+ if (this.config.defaultLogVerbose) console.warn(`failed to update field ${key}`);
3443
3485
  return;
3444
3486
  }
3445
3487
  if (path.length > 0) {
@@ -3461,7 +3503,7 @@ class FormCore {
3461
3503
  if (Array.isArray(fieldProp) || typeof fieldProp === 'object' && !isNil(fieldProp)) {
3462
3504
  propState = cloneDeep(fieldProp);
3463
3505
  } else {
3464
- this.config.defaultLogVerbose && console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
3506
+ if (this.config.defaultLogVerbose) console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
3465
3507
  return;
3466
3508
  }
3467
3509
  set(propState, path, value);
@@ -3552,8 +3594,10 @@ class FormCore {
3552
3594
  try {
3553
3595
  return parse ? new Function(`return ${value}`)() : value;
3554
3596
  } catch (_a) {
3555
- this.config.defaultLogVerbose && console.warn(`unhandled parsing on ${expression} returning`);
3556
- this.config.defaultLogVerbose && console.warn(value);
3597
+ if (this.config.defaultLogVerbose) {
3598
+ console.warn(`unhandled parsing on ${expression} returning`);
3599
+ console.warn(value);
3600
+ }
3557
3601
  return value;
3558
3602
  }
3559
3603
  });
@@ -3704,6 +3748,9 @@ class FormCore {
3704
3748
  });
3705
3749
  }
3706
3750
  } else {
3751
+ fieldInstance.emitEvents({
3752
+ event: 'ON_FIELD_UNMOUNT'
3753
+ });
3707
3754
  if (fieldInstance.persistValue) {
3708
3755
  this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
3709
3756
  }
@@ -3970,7 +4017,6 @@ class FormCore {
3970
4017
  });
3971
4018
  } else {
3972
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) || [];
3973
- currField.path = path;
3974
4020
  currField.originalSchema = structElement;
3975
4021
  currField.templateSubject$ = this.templateSubject$;
3976
4022
  }
@@ -4067,7 +4113,7 @@ class FormCore {
4067
4113
  subscribeFieldEvent({
4068
4114
  callback
4069
4115
  }) {
4070
- 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({
4071
4117
  next: callback
4072
4118
  });
4073
4119
  return sub;
@@ -4091,7 +4137,7 @@ class FormCore {
4091
4137
  subscribeData(callback) {
4092
4138
  const sub = this.dataSubject$.pipe(filter(({
4093
4139
  formIndex
4094
- }) => 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(({
4095
4141
  fieldIndex
4096
4142
  }) => ({
4097
4143
  field: fieldIndex,
@@ -4109,7 +4155,7 @@ class FormCore {
4109
4155
  subscribeOnSubmit(callback) {
4110
4156
  const sub = this.submitSubject$.pipe(filter(({
4111
4157
  formIndex
4112
- }) => formIndex === this.index), map(({
4158
+ }) => formIndex === this.index && this.submitChecker()), map(({
4113
4159
  values
4114
4160
  }) => values)).subscribe({
4115
4161
  next: callback
@@ -4124,7 +4170,7 @@ class FormCore {
4124
4170
  subscribeFormValidation(callback) {
4125
4171
  const sub = this.formValidSubject$.pipe(filter(({
4126
4172
  formIndex
4127
- }) => this.index === formIndex), debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4173
+ }) => this.index === formIndex), map(() => ({
4128
4174
  formIndex: this.index,
4129
4175
  valid: this.valid
4130
4176
  })), distinctUntilKeyChanged('valid'), startWith({
@@ -4150,6 +4196,7 @@ class FormCore {
4150
4196
  formIndex: this.index,
4151
4197
  values
4152
4198
  });
4199
+ this.submitted = true;
4153
4200
  }
4154
4201
  /**
4155
4202
  * recycles all the Suscriptions, to be called from the adapter when the form leaves the page
@@ -4339,17 +4386,20 @@ class FormGroup {
4339
4386
  var _a, _b;
4340
4387
  (_a = this.forms.get(index)) === null || _a === void 0 ? void 0 : _a.submit();
4341
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 : {};
4342
4390
  isValid = isValid && ((res === null || res === void 0 ? void 0 : res.isValid) || false);
4343
4391
  values = Object.assign(Object.assign({}, values), (res === null || res === void 0 ? void 0 : res.values) || {});
4344
- metadata = Object.assign(Object.assign({}, metadata), (res === null || res === void 0 ? void 0 : res.metadata) || {});
4392
+ metadata = Object.assign(Object.assign({}, metadata), formMetadata);
4345
4393
  erroredFields = [...erroredFields, ...((res === null || res === void 0 ? void 0 : res.erroredFields) || [])];
4346
4394
  });
4347
- isValid && callback && callback({
4348
- erroredFields,
4349
- isValid,
4350
- values,
4351
- metadata
4352
- });
4395
+ if (isValid && callback) {
4396
+ callback({
4397
+ erroredFields,
4398
+ isValid,
4399
+ values,
4400
+ metadata
4401
+ });
4402
+ }
4353
4403
  }
4354
4404
  onDataSubscription({
4355
4405
  ids,
@@ -4384,7 +4434,7 @@ class FormGroup {
4384
4434
  formIndex
4385
4435
  }) => ids.includes(formIndex)), groupBy(({
4386
4436
  formIndex
4387
- }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4437
+ }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(0))), startWith({
4388
4438
  fieldTrigger: null
4389
4439
  }), map(() => ({
4390
4440
  groupValid: ids.every(id => {
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine-core",
3
- "version": "1.0.2-beta.1",
3
+ "version": "1.0.2",
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
- "dependencies": {
8
- "@gaignoux/currency": "1.1.0",
9
- "credit-card-type": "10.0.1",
10
- "lodash": "4.17.21",
11
- "react": "18.2.0",
12
- "rxjs": "7.8.1"
13
- },
14
- "peerDependencies": {}
15
- }
13
+ "types": "./index.d.ts"
14
+ }
package/index.esm.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./src/index";
@@ -1,10 +0,0 @@
1
- declare const DEFAULT_API_DEBOUNCE_TIME = 1000;
2
- declare const DEFAULT_STATE_REFRESH_TIME = 100;
3
- declare const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR: RegExp;
4
- declare const TEMPLATE_REGEX_DELIMITATOR: RegExp;
5
- declare const TEMPLATE_REGEX_OPERATOR_SPLITTER: RegExp;
6
- declare const TEMPLATE_REGEX_OPERATOR_MATCHER: RegExp;
7
- 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 DEFAULT_LOG_VERBOSE = false;
10
- 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, };
@@ -1,23 +0,0 @@
1
- import { TFormatters } from '../types/schema';
2
- /**
3
- * Formats a credit card number by adding gaps based on the card type.
4
- *
5
- * @param {unknown} value - The input value to be formatted, expected to be a string representing a credit card number.
6
- * @param {TFormatters} formatters - An object containing formatting options.
7
- * @param {boolean} formatters.gapsCreditCard - A flag indicating whether to apply credit card gap formatting.
8
- * @returns {unknown} - The formatted credit card number with appropriate gaps, or the original value if formatting is not applied.
9
- *
10
- * @example
11
- * ```typescript
12
- * const formatters = { gapsCreditCard: true };
13
- * const result = gapsCreditCard('4111111111111111', formatters);
14
- * console.log(result); // "4111 1111 1111 1111" (formatted based on card type, e.g., Visa)
15
- * ```
16
- * @example
17
- * ```typescript
18
- * const formatters = { gapsCreditCard: false };
19
- * const result = gapsCreditCard('4111111111111111', formatters);
20
- * console.log(result); // "4111111111111111" (no formatting applied)
21
- * ```
22
- */
23
- export declare const gapsCreditCard: (value: unknown, formatters: TFormatters) => unknown;
@@ -1,29 +0,0 @@
1
- import { TFormatters } from '../types/schema';
2
- /**
3
- * Applies a custom callback function to format a value.
4
- *
5
- * @param {unknown} value - The input value to be formatted.
6
- * @param {TFormatters} formatters - An object containing formatting options.
7
- * @param {(value: unknown) => unknown} formatters.callback - A custom callback function to apply to the value.
8
- * @returns {unknown} - The value after applying the custom callback function, or the original value if no callback is provided.
9
- *
10
- * @example
11
- * ```typescript
12
- * const formatters = { callback: (val) => `Formatted: ${val}` };
13
- * const result = callback('example', formatters);
14
- * console.log(result); // "Formatted: example"
15
- * ```
16
- * @example
17
- * ```typescript
18
- * const formatters = { callback: (val) => val.toString().toUpperCase() };
19
- * const result = callback('example', formatters);
20
- * console.log(result); // "EXAMPLE"
21
- * ```
22
- * @example
23
- * ```typescript
24
- * const formatters = { callback: null };
25
- * const result = callback('example', formatters);
26
- * console.log(result); // "example" (no formatting applied)
27
- * ```
28
- */
29
- export declare const callback: (value: unknown, formatters: TFormatters) => unknown;
@@ -1,2 +0,0 @@
1
- import { TFormatters } from '../types/schema';
2
- export declare const formatters: Record<keyof TFormatters, (value: unknown, formatters?: TFormatters) => unknown>;
@@ -1,47 +0,0 @@
1
- import { TFormatters } from '../types/schema';
2
- /**
3
- * Removes all non-numeric characters from a string.
4
- *
5
- * @param value - The value to be processed.
6
- * @returns The processed value with only numbers.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { onlyNumbers } from './path/to/formatterFunctions';
11
- *
12
- * const processedValue = onlyNumbers('abc123def456');
13
- * console.log(processedValue); // Output: '123456'
14
- * ```
15
- */
16
- export declare const onlyNumbers: (value: unknown) => string;
17
- /**
18
- * Removes all non-letter characters from a string.
19
- *
20
- * @param value - The value to be processed.
21
- * @returns The processed value with only letters.
22
- *
23
- * @example
24
- * ```typescript
25
- * import { onlyLetters } from './path/to/formatterFunctions';
26
- *
27
- * const processedValue = onlyLetters('abc123def456');
28
- * console.log(processedValue); // Output: 'abcdef'
29
- * ```
30
- */
31
- export declare const onlyLetters: (value: unknown) => string;
32
- /**
33
- * Applies a regular expression pattern to remove matching substrings from a string.
34
- *
35
- * @param value - The value to be processed.
36
- * @param formatters - An object containing formatting options.
37
- * @returns The processed value with matched substrings removed.
38
- *
39
- * @example
40
- * ```typescript
41
- * import { regex } from './path/to/formatterFunctions';
42
- *
43
- * const processedValue = regex('abc123def456', { regex: '\\d+' });
44
- * console.log(processedValue); // Output: 'abcdef'
45
- * ```
46
- */
47
- export declare const regex: (value: unknown, formatters: TFormatters) => unknown;
@@ -1,17 +0,0 @@
1
- import { TFormatters } from '../types/schema';
2
- /**
3
- * Splits a string by inserting specified values at given positions.
4
- *
5
- * @param value - The value to be processed.
6
- * @param formatters - An object containing formatting options.
7
- * @returns The processed value with splitters applied.
8
- *
9
- * @example
10
- * ```typescript
11
- * import { splitter } from './path/to/formatterFunctions';
12
- *
13
- * const processedValue = splitter('HelloWorld', { splitter: [{ position: 5, value: '_' }] });
14
- * console.log(processedValue); // Output: 'Hello_World'
15
- * ```
16
- */
17
- export declare const splitter: (value: unknown, formatters: TFormatters) => unknown;