@bolttech/form-engine-core 1.0.2-beta.2 → 1.0.3

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 +2327 -0
  2. package/index.esm.js +154 -82
  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
  /**
@@ -2497,7 +2505,6 @@ class FormField {
2497
2505
  formIndex,
2498
2506
  schemaComponent,
2499
2507
  config,
2500
- path,
2501
2508
  children,
2502
2509
  validateVisibility,
2503
2510
  resetValue,
@@ -2526,7 +2533,6 @@ class FormField {
2526
2533
  this.name = schemaComponent.name;
2527
2534
  this.nameToSubmit = schemaComponent.nameToSubmit;
2528
2535
  this.component = schemaComponent.component;
2529
- this.path = path;
2530
2536
  this.children = children;
2531
2537
  this.validations = cloneDeep(schemaComponent.validations);
2532
2538
  this.visibilityConditions = cloneDeep(schemaComponent.visibilityConditions);
@@ -2549,6 +2555,7 @@ class FormField {
2549
2555
  this.fieldValidNotification$ = fieldValidNotification$;
2550
2556
  this.mountSubject$ = mountSubject$;
2551
2557
  this._props = FormField.filterProps(cloneDeep(schemaComponent.props || {}));
2558
+ this._adapterProps = JSON.stringify(schemaComponent.props || {});
2552
2559
  this._metadata = '';
2553
2560
  this.errorsString = '';
2554
2561
  this.errorsList = [];
@@ -2600,11 +2607,35 @@ 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
+ }
2617
+ }
2618
+ /**
2619
+ * Retrieves the raw props sent from the adapter.
2620
+ *
2621
+ * @returns {string} - raw props from the adapter
2622
+ */
2623
+ get adapterProps() {
2624
+ return this._adapterProps;
2625
+ }
2626
+ /**
2627
+ * compares adapter props changes and emits the change if they effectively changed
2628
+ * preventing an emission from the adapter of the same props that can overwrite other prop
2629
+ * changes via templating
2630
+ */
2631
+ set adapterProps(props) {
2632
+ const currentProps = JSON.stringify(props || {});
2633
+ // it's a very basic comparison to determine if props changed,
2634
+ // will need review if we need complex comparisons
2635
+ if (currentProps !== this.adapterProps) {
2636
+ this.props = FormField.filterProps(props);
2637
+ this._adapterProps = currentProps;
2638
+ }
2608
2639
  }
2609
2640
  /**
2610
2641
  * Retrieves the properties associated with the form field.
@@ -2709,7 +2740,9 @@ class FormField {
2709
2740
  this.maskValue(this.formatValue(val));
2710
2741
  this._metadata = val;
2711
2742
  }
2712
- this.stateValue && this.valueSubject$.next(this.stateValue);
2743
+ if (this.stateValue) {
2744
+ this.valueSubject$.next(this.stateValue);
2745
+ }
2713
2746
  this.templateSubject$.next({
2714
2747
  scope: 'fields',
2715
2748
  key: this.name,
@@ -2763,9 +2796,11 @@ class FormField {
2763
2796
  * if form instance onValid or template form.valid doesn't work properly, might be due to this workaround
2764
2797
  */
2765
2798
  triggerFieldValidNotification() {
2766
- !this.fieldValidNotification$.closed && this.fieldValidNotification$.next({
2767
- fieldTrigger: this.name
2768
- });
2799
+ if (!this.fieldValidNotification$.closed) {
2800
+ this.fieldValidNotification$.next({
2801
+ fieldTrigger: this.name
2802
+ });
2803
+ }
2769
2804
  }
2770
2805
  /**
2771
2806
  * Retrieves the error messages associated with the form field.
@@ -2784,14 +2819,16 @@ class FormField {
2784
2819
  var _a;
2785
2820
  if (typeof errors === 'undefined' || isEqual(errors, this.errors)) return;
2786
2821
  this._errors = errors;
2787
- this.errorsList = Object.values(this.errors);
2822
+ this.errorsList = Object.values(this.errors).filter(el => el !== undefined && el !== null);
2788
2823
  this.errorsString = this.errorsList.join(', ');
2789
2824
  /**
2790
2825
  * if any error receives a list of errors, set a prop for it, currently only supporting a single string
2791
2826
  */
2792
- ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) && this.errorSubject$.next({
2793
- [this.mapper.events.setErrorMessage]: this.errorsString
2794
- });
2827
+ if ((_a = this.mapper.events) === null || _a === void 0 ? void 0 : _a.setErrorMessage) {
2828
+ this.errorSubject$.next({
2829
+ [this.mapper.events.setErrorMessage]: this.errorsString
2830
+ });
2831
+ }
2795
2832
  this.templateSubject$.next({
2796
2833
  scope: 'fields',
2797
2834
  key: this.name,
@@ -2955,23 +2992,25 @@ class FormField {
2955
2992
  let valid = true;
2956
2993
  const errors = {};
2957
2994
  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;
2995
+ if (schemaValidations) {
2996
+ Object.keys(schemaValidations).forEach(validationKey => {
2997
+ var _a;
2998
+ const error = handleValidation(this.value, schemaValidations, validations, validationKey);
2999
+ // setting valid flag
3000
+ valid = !error && valid;
3001
+ // setting error messages
3002
+ if (error && ((_a = this.validations) === null || _a === void 0 ? void 0 : _a.messages)) {
3003
+ if (validationKey in this.validations.messages) {
3004
+ const messages = this.validations.messages;
3005
+ errors[validationKey] = messages[validationKey];
3006
+ } else if ('default' in this.validations.messages) {
3007
+ errors[validationKey] = this.validations.messages.default;
3008
+ }
3009
+ } else {
3010
+ delete errors[validationKey];
2970
3011
  }
2971
- } else {
2972
- delete errors[validationKey];
2973
- }
2974
- });
3012
+ });
3013
+ }
2975
3014
  this.valid = valid;
2976
3015
  if ((_c = (_b = this.validations) === null || _b === void 0 ? void 0 : _b.eventMessages) === null || _c === void 0 ? void 0 : _c[event]) {
2977
3016
  const eventMessages = {};
@@ -3016,10 +3055,12 @@ class FormField {
3016
3055
  checkApiRequestValidations(config) {
3017
3056
  let valid = true;
3018
3057
  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
- });
3058
+ if (preConditions) {
3059
+ Object.keys(preConditions).forEach(validationKey => {
3060
+ const error = handleValidation(this.value, preConditions, validations, validationKey);
3061
+ valid = valid && !error;
3062
+ });
3063
+ }
3023
3064
  if (config.blockRequestWhenInvalid) {
3024
3065
  valid = valid && this.valid;
3025
3066
  }
@@ -3031,20 +3072,20 @@ class FormField {
3031
3072
  * @param {TEvents} event - The event type associated with the API request.
3032
3073
  * @returns {Promise<void>}
3033
3074
  */
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* () {
3075
+ apiRequest(_a) {
3076
+ return __awaiter(this, arguments, void 0, function* ({
3077
+ event
3078
+ }) {
3079
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k;
3039
3080
  let requestMadeOnce = false;
3040
3081
  const configRequest = config => __awaiter(this, void 0, void 0, function* () {
3041
- var _k;
3082
+ var _a;
3042
3083
  try {
3043
3084
  const {
3044
3085
  status,
3045
3086
  response
3046
3087
  } = 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;
3088
+ const callbackTransform = (_a = config.transform) === null || _a === void 0 ? void 0 : _a.callback;
3048
3089
  const apiResponseData = callbackTransform ? callbackTransform({
3049
3090
  payload: JSON.parse(String(response)),
3050
3091
  formValues: this.getFormValues()
@@ -3062,7 +3103,7 @@ class FormField {
3062
3103
  };
3063
3104
  }
3064
3105
  });
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 => {
3106
+ 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
3107
  var _a, _b;
3067
3108
  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
3109
  }))) return;
@@ -3071,9 +3112,11 @@ class FormField {
3071
3112
  named: Object.assign({}, this.api.named),
3072
3113
  apiState: Object.assign({}, this.api.apiState)
3073
3114
  };
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();
3115
+ const config = (_f = this.apiSchema.defaultConfig) === null || _f === void 0 ? void 0 : _f.config;
3116
+ 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)) {
3117
+ if (!requestMadeOnce) {
3118
+ this.notifyApiRequest();
3119
+ }
3077
3120
  const {
3078
3121
  response,
3079
3122
  status
@@ -3084,7 +3127,7 @@ class FormField {
3084
3127
  status
3085
3128
  };
3086
3129
  }
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 => {
3130
+ 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
3131
  var _a, _b;
3089
3132
  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
3133
  })) {
@@ -3093,10 +3136,12 @@ class FormField {
3093
3136
  @TODO handle promises with error
3094
3137
  */
3095
3138
  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();
3139
+ var _a, _b, _c, _d;
3140
+ const config = (_b = (_a = this.apiSchema) === null || _a === void 0 ? void 0 : _a.configs) === null || _b === void 0 ? void 0 : _b[configKey].config;
3141
+ 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)) {
3142
+ if (!requestMadeOnce) {
3143
+ this.notifyApiRequest();
3144
+ }
3100
3145
  const {
3101
3146
  response,
3102
3147
  status
@@ -3137,12 +3182,12 @@ class FormField {
3137
3182
  this.propsSubject$.unsubscribe();
3138
3183
  this.errorSubject$.unsubscribe();
3139
3184
  this.apiEventQueueSubject$.unsubscribe();
3140
- this.dataSubject$.next({
3185
+ if (!this.dataSubject$.closed) this.dataSubject$.next({
3141
3186
  event: 'ON_FIELD_UNMOUNT',
3142
3187
  fieldIndex: this.name,
3143
3188
  formIndex: this.formIndex
3144
3189
  });
3145
- !this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
3190
+ if (!this.fieldEventSubject$.closed) this.fieldEventSubject$.next({
3146
3191
  event: 'ON_FIELD_UNMOUNT',
3147
3192
  fieldName: this.name,
3148
3193
  fieldInstance: this
@@ -3203,6 +3248,8 @@ class FormCore {
3203
3248
  this.queuedFieldResetPropertyEvents = new Map();
3204
3249
  this.queuedInitialValues = new Map();
3205
3250
  this._valid = false;
3251
+ this.stopEventsOnSubmit = false;
3252
+ this.submitted = false;
3206
3253
  this.index = entry.index;
3207
3254
  this.schema = entry.schema;
3208
3255
  this.fields = new Map();
@@ -3217,7 +3264,9 @@ class FormCore {
3217
3264
  this.mappers.set(mapper.componentName, mapper);
3218
3265
  });
3219
3266
  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);
3267
+ if (this.schema) {
3268
+ FormCore.checkIndexes(this.schema.components);
3269
+ }
3221
3270
  this.templateSubject$ = new Subject();
3222
3271
  this.fieldEventSubject$ = new Subject();
3223
3272
  this.mountSubject$ = new Subject();
@@ -3233,12 +3282,16 @@ class FormCore {
3233
3282
  this.mountSubject$.subscribe(this.mountActions.bind(this));
3234
3283
  this.initialValues = entry.initialValues || ((_j = entry.schema) === null || _j === void 0 ? void 0 : _j.initialValues);
3235
3284
  this.iVars = entry.iVars || ((_k = entry.schema) === null || _k === void 0 ? void 0 : _k.iVars) || {};
3285
+ this.stopEventsOnSubmit = (entry === null || entry === void 0 ? void 0 : entry.stopEventsOnSubmit) || false;
3286
+ this.submitted = false;
3236
3287
  }
3237
3288
  /**
3238
3289
  * mock function to simulate form mount onto the adapter
3239
3290
  */
3240
3291
  generateFields() {
3241
- this.schema && this.serializeStructure(this.schema.components);
3292
+ if (this.schema) {
3293
+ this.serializeStructure(this.schema.components);
3294
+ }
3242
3295
  this.fields.forEach(field => {
3243
3296
  field.mountField({
3244
3297
  valueSubscription: () => null,
@@ -3246,6 +3299,13 @@ class FormCore {
3246
3299
  });
3247
3300
  });
3248
3301
  }
3302
+ /**
3303
+ *flag utility to prevent Subjects from emitting after form submission and stopEventsOnSubmit
3304
+ * @returns {boolean} - result of the flag utility.
3305
+ */
3306
+ submitChecker() {
3307
+ return !(this.stopEventsOnSubmit && this.submitted);
3308
+ }
3249
3309
  /**
3250
3310
  * callback function passed to field instance to notify field adapter mount status
3251
3311
  * once the field has all field instance properties set, this function will handle all
@@ -3265,7 +3325,7 @@ class FormCore {
3265
3325
  @TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
3266
3326
  since they are dependent on adapter field recycling runtimes
3267
3327
  */
3268
- this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3328
+ 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
3329
  return;
3270
3330
  }
3271
3331
  this.subscribeTemplates();
@@ -3277,12 +3337,16 @@ class FormCore {
3277
3337
  scope: 'iVars',
3278
3338
  event: 'ON_IVARS'
3279
3339
  });
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
- });
3340
+ if (!this.queuedInitialValues.has(key)) if (field.valuePropName && !field.value) {
3341
+ field.emitValue({
3342
+ event: 'ON_FIELD_MOUNT',
3343
+ value: ''
3344
+ });
3345
+ } else {
3346
+ field.emitEvents({
3347
+ event: 'ON_FIELD_MOUNT'
3348
+ });
3349
+ }
3286
3350
  this.checkFieldEventQueues(key);
3287
3351
  }
3288
3352
  }
@@ -3439,7 +3503,7 @@ class FormCore {
3439
3503
  }) {
3440
3504
  const field = this.fields.get(key);
3441
3505
  if (!field) {
3442
- this.config.defaultLogVerbose && console.warn(`failed to update field ${key}`);
3506
+ if (this.config.defaultLogVerbose) console.warn(`failed to update field ${key}`);
3443
3507
  return;
3444
3508
  }
3445
3509
  if (path.length > 0) {
@@ -3461,7 +3525,7 @@ class FormCore {
3461
3525
  if (Array.isArray(fieldProp) || typeof fieldProp === 'object' && !isNil(fieldProp)) {
3462
3526
  propState = cloneDeep(fieldProp);
3463
3527
  } else {
3464
- this.config.defaultLogVerbose && console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
3528
+ if (this.config.defaultLogVerbose) console.warn(`invalid template property, skipping evaluation of ${field.name} with ${fieldProp}`);
3465
3529
  return;
3466
3530
  }
3467
3531
  set(propState, path, value);
@@ -3552,8 +3616,10 @@ class FormCore {
3552
3616
  try {
3553
3617
  return parse ? new Function(`return ${value}`)() : value;
3554
3618
  } catch (_a) {
3555
- this.config.defaultLogVerbose && console.warn(`unhandled parsing on ${expression} returning`);
3556
- this.config.defaultLogVerbose && console.warn(value);
3619
+ if (this.config.defaultLogVerbose) {
3620
+ console.warn(`unhandled parsing on ${expression} returning`);
3621
+ console.warn(value);
3622
+ }
3557
3623
  return value;
3558
3624
  }
3559
3625
  });
@@ -3704,6 +3770,9 @@ class FormCore {
3704
3770
  });
3705
3771
  }
3706
3772
  } else {
3773
+ fieldInstance.emitEvents({
3774
+ event: 'ON_FIELD_UNMOUNT'
3775
+ });
3707
3776
  if (fieldInstance.persistValue) {
3708
3777
  this.queuedInitialValues.set(fieldInstance.name, fieldInstance.value);
3709
3778
  }
@@ -3970,7 +4039,6 @@ class FormCore {
3970
4039
  });
3971
4040
  } else {
3972
4041
  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
4042
  currField.originalSchema = structElement;
3975
4043
  currField.templateSubject$ = this.templateSubject$;
3976
4044
  }
@@ -4067,7 +4135,7 @@ class FormCore {
4067
4135
  subscribeFieldEvent({
4068
4136
  callback
4069
4137
  }) {
4070
- const sub = this.fieldEventSubject$.pipe(groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
4138
+ const sub = this.fieldEventSubject$.pipe(filter(() => this.submitChecker()), groupBy(payload => `${payload.event}|${payload.fieldName}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS)))).subscribe({
4071
4139
  next: callback
4072
4140
  });
4073
4141
  return sub;
@@ -4091,7 +4159,7 @@ class FormCore {
4091
4159
  subscribeData(callback) {
4092
4160
  const sub = this.dataSubject$.pipe(filter(({
4093
4161
  formIndex
4094
- }) => this.index === formIndex), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4162
+ }) => this.index === formIndex && this.submitChecker()), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4095
4163
  fieldIndex
4096
4164
  }) => ({
4097
4165
  field: fieldIndex,
@@ -4109,7 +4177,7 @@ class FormCore {
4109
4177
  subscribeOnSubmit(callback) {
4110
4178
  const sub = this.submitSubject$.pipe(filter(({
4111
4179
  formIndex
4112
- }) => formIndex === this.index), map(({
4180
+ }) => formIndex === this.index && this.submitChecker()), map(({
4113
4181
  values
4114
4182
  }) => values)).subscribe({
4115
4183
  next: callback
@@ -4124,7 +4192,7 @@ class FormCore {
4124
4192
  subscribeFormValidation(callback) {
4125
4193
  const sub = this.formValidSubject$.pipe(filter(({
4126
4194
  formIndex
4127
- }) => this.index === formIndex), debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4195
+ }) => this.index === formIndex), map(() => ({
4128
4196
  formIndex: this.index,
4129
4197
  valid: this.valid
4130
4198
  })), distinctUntilKeyChanged('valid'), startWith({
@@ -4150,6 +4218,7 @@ class FormCore {
4150
4218
  formIndex: this.index,
4151
4219
  values
4152
4220
  });
4221
+ this.submitted = true;
4153
4222
  }
4154
4223
  /**
4155
4224
  * recycles all the Suscriptions, to be called from the adapter when the form leaves the page
@@ -4339,17 +4408,20 @@ class FormGroup {
4339
4408
  var _a, _b;
4340
4409
  (_a = this.forms.get(index)) === null || _a === void 0 ? void 0 : _a.submit();
4341
4410
  const res = (_b = this.forms.get(index)) === null || _b === void 0 ? void 0 : _b.getFormValues();
4411
+ const formMetadata = typeof (res === null || res === void 0 ? void 0 : res.metadata) === 'object' && res.metadata !== null ? res.metadata : {};
4342
4412
  isValid = isValid && ((res === null || res === void 0 ? void 0 : res.isValid) || false);
4343
4413
  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) || {});
4414
+ metadata = Object.assign(Object.assign({}, metadata), formMetadata);
4345
4415
  erroredFields = [...erroredFields, ...((res === null || res === void 0 ? void 0 : res.erroredFields) || [])];
4346
4416
  });
4347
- isValid && callback && callback({
4348
- erroredFields,
4349
- isValid,
4350
- values,
4351
- metadata
4352
- });
4417
+ if (isValid && callback) {
4418
+ callback({
4419
+ erroredFields,
4420
+ isValid,
4421
+ values,
4422
+ metadata
4423
+ });
4424
+ }
4353
4425
  }
4354
4426
  onDataSubscription({
4355
4427
  ids,
@@ -4384,7 +4456,7 @@ class FormGroup {
4384
4456
  formIndex
4385
4457
  }) => ids.includes(formIndex)), groupBy(({
4386
4458
  formIndex
4387
- }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4459
+ }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(0))), startWith({
4388
4460
  fieldTrigger: null
4389
4461
  }), map(() => ({
4390
4462
  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.2",
3
+ "version": "1.0.3",
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;