@zajno/common 1.3.14 → 1.4.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.
Files changed (100) hide show
  1. package/coverage/clover.xml +112 -99
  2. package/coverage/coverage-final.json +7 -7
  3. package/coverage/lcov-report/index.html +19 -19
  4. package/coverage/lcov-report/src/__tests__/helpers/index.html +1 -1
  5. package/coverage/lcov-report/src/__tests__/helpers/main.ts.html +1 -1
  6. package/coverage/lcov-report/src/async/arrays.ts.html +1 -1
  7. package/coverage/lcov-report/src/async/index.html +1 -1
  8. package/coverage/lcov-report/src/dates/calc.ts.html +1 -1
  9. package/coverage/lcov-report/src/dates/convert.ts.html +1 -1
  10. package/coverage/lcov-report/src/dates/datex.ts.html +1 -1
  11. package/coverage/lcov-report/src/dates/format.ts.html +1 -1
  12. package/coverage/lcov-report/src/dates/index.html +1 -1
  13. package/coverage/lcov-report/src/dates/index.ts.html +1 -1
  14. package/coverage/lcov-report/src/dates/parse.ts.html +1 -1
  15. package/coverage/lcov-report/src/dates/period.ts.html +1 -1
  16. package/coverage/lcov-report/src/dates/shift.ts.html +1 -1
  17. package/coverage/lcov-report/src/dates/types.ts.html +1 -1
  18. package/coverage/lcov-report/src/dates/yearDate.ts.html +1 -1
  19. package/coverage/lcov-report/src/enumHelper.ts.html +1 -1
  20. package/coverage/lcov-report/src/event.ts.html +1 -1
  21. package/coverage/lcov-report/src/fields/index.html +1 -1
  22. package/coverage/lcov-report/src/fields/update.ts.html +1 -1
  23. package/coverage/lcov-report/src/functions.ts.html +1 -1
  24. package/coverage/lcov-report/src/index.html +1 -1
  25. package/coverage/lcov-report/src/lazy.light.ts.html +4 -4
  26. package/coverage/lcov-report/src/logger/batch.ts.html +1 -1
  27. package/coverage/lcov-report/src/logger/console.ts.html +1 -1
  28. package/coverage/lcov-report/src/logger/index.html +1 -1
  29. package/coverage/lcov-report/src/logger/index.ts.html +1 -1
  30. package/coverage/lcov-report/src/logger/named.ts.html +1 -1
  31. package/coverage/lcov-report/src/logger/proxy.ts.html +1 -1
  32. package/coverage/lcov-report/src/math/arrays.ts.html +1 -1
  33. package/coverage/lcov-report/src/math/calc.ts.html +1 -1
  34. package/coverage/lcov-report/src/math/distribution.ts.html +1 -1
  35. package/coverage/lcov-report/src/math/index.html +1 -1
  36. package/coverage/lcov-report/src/math/index.ts.html +1 -1
  37. package/coverage/lcov-report/src/transitionObserver.ts.html +1 -1
  38. package/coverage/lcov-report/src/types.ts.html +1 -1
  39. package/coverage/lcov-report/src/validation/ValidationErrors.ts.html +1 -1
  40. package/coverage/lcov-report/src/validation/creditCard.ts.html +1 -1
  41. package/coverage/lcov-report/src/validation/helpers.ts.html +1 -1
  42. package/coverage/lcov-report/src/validation/index.html +1 -1
  43. package/coverage/lcov-report/src/validation/index.ts.html +1 -1
  44. package/coverage/lcov-report/src/validation/types.ts.html +6 -6
  45. package/coverage/lcov-report/src/validation/validators.ts.html +1 -1
  46. package/coverage/lcov-report/src/validation/wrappers.ts.html +1 -1
  47. package/coverage/lcov-report/src/viewModels/FlagModel.ts.html +25 -10
  48. package/coverage/lcov-report/src/viewModels/MultiSelectModel.ts.html +20 -8
  49. package/coverage/lcov-report/src/viewModels/NumberModel.ts.html +24 -9
  50. package/coverage/lcov-report/src/viewModels/SelectModel.ts.html +51 -24
  51. package/coverage/lcov-report/src/viewModels/Validatable.ts.html +74 -50
  52. package/coverage/lcov-report/src/viewModels/index.html +53 -53
  53. package/coverage/lcov-report/src/viewModels/wrappers.ts.html +1 -1
  54. package/coverage/lcov.info +278 -250
  55. package/lib/validation/types.d.ts +5 -5
  56. package/lib/validation/types.d.ts.map +1 -1
  57. package/lib/validation/types.js.map +1 -1
  58. package/lib/validation/wrappers.d.ts +4 -3
  59. package/lib/validation/wrappers.d.ts.map +1 -1
  60. package/lib/viewModels/CommonModel.d.ts +12 -0
  61. package/lib/viewModels/CommonModel.d.ts.map +1 -0
  62. package/lib/viewModels/CommonModel.js +43 -0
  63. package/lib/viewModels/CommonModel.js.map +1 -0
  64. package/lib/viewModels/FlagModel.d.ts +1 -0
  65. package/lib/viewModels/FlagModel.d.ts.map +1 -1
  66. package/lib/viewModels/FlagModel.js +8 -1
  67. package/lib/viewModels/FlagModel.js.map +1 -1
  68. package/lib/viewModels/MultiSelectModel.d.ts.map +1 -1
  69. package/lib/viewModels/MultiSelectModel.js +3 -0
  70. package/lib/viewModels/MultiSelectModel.js.map +1 -1
  71. package/lib/viewModels/NumberModel.d.ts +1 -0
  72. package/lib/viewModels/NumberModel.d.ts.map +1 -1
  73. package/lib/viewModels/NumberModel.js +8 -1
  74. package/lib/viewModels/NumberModel.js.map +1 -1
  75. package/lib/viewModels/SelectModel.d.ts +1 -0
  76. package/lib/viewModels/SelectModel.d.ts.map +1 -1
  77. package/lib/viewModels/SelectModel.js +24 -14
  78. package/lib/viewModels/SelectModel.js.map +1 -1
  79. package/lib/viewModels/TextModel.d.ts +4 -3
  80. package/lib/viewModels/TextModel.d.ts.map +1 -1
  81. package/lib/viewModels/TextModel.js +28 -24
  82. package/lib/viewModels/TextModel.js.map +1 -1
  83. package/lib/viewModels/Validatable.d.ts +10 -10
  84. package/lib/viewModels/Validatable.d.ts.map +1 -1
  85. package/lib/viewModels/Validatable.js +19 -13
  86. package/lib/viewModels/Validatable.js.map +1 -1
  87. package/lib/viewModels/index.d.ts +1 -0
  88. package/lib/viewModels/index.d.ts.map +1 -1
  89. package/lib/viewModels/index.js +1 -0
  90. package/lib/viewModels/index.js.map +1 -1
  91. package/package.json +1 -1
  92. package/src/validation/types.ts +5 -5
  93. package/src/viewModels/CommonModel.ts +40 -0
  94. package/src/viewModels/FlagModel.ts +6 -1
  95. package/src/viewModels/MultiSelectModel.ts +4 -0
  96. package/src/viewModels/NumberModel.ts +6 -1
  97. package/src/viewModels/SelectModel.ts +11 -2
  98. package/src/viewModels/TextModel.ts +24 -15
  99. package/src/viewModels/Validatable.ts +29 -21
  100. package/src/viewModels/index.ts +1 -0
@@ -1,5 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './Validatable';
3
+ export * from './CommonModel';
3
4
  export * from './TextModel';
4
5
  export * from './FlagModel';
5
6
  export * from './NumberModel';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewModels/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAE3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AAEnC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewModels/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAE3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AAEnC,cAAc,eAAe,CAAC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./types"), exports);
5
5
  tslib_1.__exportStar(require("./Validatable"), exports);
6
+ tslib_1.__exportStar(require("./CommonModel"), exports);
6
7
  tslib_1.__exportStar(require("./TextModel"), exports);
7
8
  tslib_1.__exportStar(require("./FlagModel"), exports);
8
9
  tslib_1.__exportStar(require("./NumberModel"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/viewModels/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,wDAA8B;AAC9B,sDAA4B;AAC5B,sDAA4B;AAC5B,wDAA8B;AAC9B,qDAA2B;AAE3B,wDAA8B;AAC9B,6DAAmC;AAEnC,wDAA8B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/viewModels/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,wDAA8B;AAC9B,wDAA8B;AAC9B,sDAA4B;AAC5B,sDAA4B;AAC5B,wDAA8B;AAC9B,qDAA2B;AAE3B,wDAA8B;AAC9B,6DAAmC;AAEnC,wDAA8B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zajno/common",
3
- "version": "1.3.14",
3
+ "version": "1.4.1",
4
4
  "description": "Zajno's re-usable utilities for JS/TS projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,14 +1,14 @@
1
1
  import { ValidationErrors } from './ValidationErrors';
2
2
 
3
- export type ValidatorFunction<T = string> = (val: T) => ValidationErrors;
4
- export type ValidatorFunctionAsync<T = string> = (val: T) => Promise<ValidationErrors>;
3
+ export type ValidatorFunction<T = string, TErrors = ValidationErrors> = (val: T) => TErrors;
4
+ export type ValidatorFunctionAsync<T = string, TErrors = ValidationErrors> = (val: T) => Promise<TErrors>;
5
5
 
6
6
  export type WrapperFunction = (val: ValidatorFunction) => ValidatorFunction;
7
7
 
8
- export class ValidationError extends Error {
9
- readonly code: ValidationErrors = null;
8
+ export class ValidationError<TErrors = ValidationErrors> extends Error {
9
+ readonly code: TErrors = null;
10
10
 
11
- constructor(message: string, code: ValidationErrors) {
11
+ constructor(message: string, code: TErrors) {
12
12
  super(message);
13
13
  this.code = code;
14
14
  }
@@ -0,0 +1,40 @@
1
+ import { action, makeObservable, observable } from 'mobx';
2
+ import { ValidatableModel } from './Validatable';
3
+
4
+ export class CommonModel<T = any> extends ValidatableModel<T> {
5
+
6
+ @observable.ref
7
+ private _value: T = null;
8
+
9
+ private _defaultValue: T = null;
10
+
11
+ constructor(v: T = null) {
12
+ super();
13
+ makeObservable(this);
14
+ this._value = v;
15
+ this._defaultValue = v;
16
+ }
17
+
18
+ protected get valueToValidate(): Readonly<T> {
19
+ return this._value;
20
+ }
21
+
22
+ public get value() { return this._value; }
23
+ public set value(v: T) {
24
+ this.setValue(v);
25
+ }
26
+
27
+ @action
28
+ public readonly setValue = (value: T) => {
29
+ this._value = value;
30
+
31
+ if (this._validateOnChange) {
32
+ this.validate();
33
+ }
34
+ };
35
+
36
+ reset = () => {
37
+ super.reset();
38
+ this.value = this._defaultValue;
39
+ };
40
+ }
@@ -27,9 +27,14 @@ export class FlagModel implements IFlagModel, IFlagModelReadonly {
27
27
  }
28
28
 
29
29
  set value(value: boolean) {
30
- this._value = value;
30
+ this.setValue(value);
31
31
  }
32
32
 
33
+ @action
34
+ public readonly setValue = (value: boolean) => {
35
+ this._value = value;
36
+ };
37
+
33
38
  get isDefault() { return this._value === false; }
34
39
 
35
40
  @action
@@ -109,6 +109,10 @@ export class MultiSelect<T = any> extends ValidatableModel<ReadonlyArray<T>> imp
109
109
  this._indexes.delete(index);
110
110
  }
111
111
 
112
+ if (this._validateOnChange) {
113
+ this.validate();
114
+ }
115
+
112
116
  if (!this._flags.hasValue) {
113
117
  return;
114
118
  }
@@ -20,7 +20,12 @@ export class NumberModel implements INumberModel, IValueModel<number> {
20
20
  }
21
21
 
22
22
  get value() { return this._value; }
23
- set value(v: number) { this._value = v; }
23
+ set value(v: number) { this.setValue(v); }
24
+
25
+ @action
26
+ public readonly setValue = (v: number) => {
27
+ this._value = v;
28
+ };
24
29
 
25
30
  get isDefault() { return this._value === this._initial; }
26
31
 
@@ -1,5 +1,5 @@
1
1
  import { createLazy } from '../lazy.light';
2
- import { observable, computed, makeObservable, reaction } from 'mobx';
2
+ import { observable, computed, makeObservable, reaction, action } from 'mobx';
3
3
  import { FlagModel, ILabeledFlagModel } from './FlagModel';
4
4
  import { ValidatableModel } from './Validatable';
5
5
  import { IValueModel } from './types';
@@ -75,12 +75,21 @@ export class Select<T = any> extends ValidatableModel<T> implements IValueModel<
75
75
  }
76
76
 
77
77
  set index(val: number) {
78
+ this.setIndex(val);
79
+ }
80
+
81
+ @action
82
+ public setIndex = (val: number) => {
78
83
  if (this._indexLocked) {
79
84
  return;
80
85
  }
81
86
 
82
87
  this._index = val;
83
88
 
89
+ if (this._validateOnChange) {
90
+ this.validate();
91
+ }
92
+
84
93
  // update all flags to be properly selected
85
94
  try {
86
95
  this._indexLocked = true;
@@ -91,7 +100,7 @@ export class Select<T = any> extends ValidatableModel<T> implements IValueModel<
91
100
  } finally {
92
101
  this._indexLocked = false;
93
102
  }
94
- }
103
+ };
95
104
 
96
105
  reset = () => {
97
106
  super.reset();
@@ -1,8 +1,8 @@
1
- import { observable, computed, makeObservable, reaction } from 'mobx';
1
+ import { observable, makeObservable, reaction, action } from 'mobx';
2
2
  import { Getter } from '../types';
3
3
  import { IValueModel } from './types';
4
4
  import logger from '../logger';
5
- import { ValidatableModel, ValidationConfig } from './Validatable';
5
+ import { ValidatableModel } from './Validatable';
6
6
  import { IResetableModel } from 'viewModels';
7
7
 
8
8
  export type TextInputConfig = {
@@ -11,7 +11,6 @@ export type TextInputConfig = {
11
11
  value?: Getter<string>;
12
12
  async?: boolean;
13
13
 
14
- validation?: ValidationConfig<string>;
15
14
  noSubscribe?: boolean;
16
15
  };
17
16
 
@@ -40,23 +39,20 @@ export class Text {
40
39
  get value() { return this._value; }
41
40
  }
42
41
 
43
- export class TextInputVM extends ValidatableModel implements IValueModel<string>, IResetableModel {
42
+ export class TextInputVM extends ValidatableModel<string> implements IValueModel<string>, IResetableModel {
44
43
  @observable
45
44
  private _value = '';
46
45
 
47
46
  @observable
48
47
  private _focused = false;
49
48
 
50
- @observable
51
49
  private _name: string = null;
52
-
53
- @observable
54
50
  private _title: string = null;
55
51
 
56
52
  private readonly _valueObserving: () => void = null;
57
53
 
58
54
  constructor(config?: TextInputConfig) {
59
- super(config && config.validation);
55
+ super();
60
56
  makeObservable(this);
61
57
  config = config || {};
62
58
 
@@ -72,14 +68,22 @@ export class TextInputVM extends ValidatableModel implements IValueModel<string>
72
68
  get title() { return this._title; }
73
69
 
74
70
  set value(val) {
71
+ this.setValue(val);
72
+ }
73
+
74
+ @action
75
+ public readonly setValue = (value: string) => {
75
76
  if (!this._valueObserving) {
76
- this._value = val;
77
+ this._value = value;
78
+
79
+ if (this._validateOnChange) {
80
+ this.validate();
81
+ }
77
82
  } else {
78
83
  logger.warn('[TextInputViewModel] Setting value is not allowed when value is observing');
79
84
  }
80
- }
85
+ };
81
86
 
82
- @computed
83
87
  get isEmpty() {
84
88
  return !this._value;
85
89
  }
@@ -88,15 +92,20 @@ export class TextInputVM extends ValidatableModel implements IValueModel<string>
88
92
  return this._focused;
89
93
  }
90
94
 
91
- set focused(val) {
92
- this._focused = val;
93
- if (!val) {
95
+ set focused(val: boolean) {
96
+ this.setFocused(val);
97
+ }
98
+
99
+ @action
100
+ public readonly setFocused = (value = true) => {
101
+ this._focused = value;
102
+ if (!value) {
94
103
  this.onBlur();
95
104
  return;
96
105
  }
97
106
 
98
107
  super.reset();
99
- }
108
+ };
100
109
 
101
110
  protected get valueToValidate() { return (this.value ?? '').trim(); }
102
111
 
@@ -1,29 +1,30 @@
1
- import { observable, makeObservable, action } from 'mobx';
1
+ import { observable, makeObservable, action, runInAction } from 'mobx';
2
2
  import { ValidatorFunction, ValidatorFunctionAsync, ValidationErrors, ValidationError } from '../validation';
3
3
  import { someAsync } from '../async/arrays';
4
4
 
5
- export type ValueValidator<T> = ValidatorFunction<T> | ValidatorFunctionAsync<T>;
6
- export type ValidationErrorsStrings = { [code: number]: string };
5
+ export type ValueValidator<T, TErrors = ValidationErrors> = ValidatorFunction<T, TErrors> | ValidatorFunctionAsync<T, TErrors>;
6
+ export type ValidationErrorsStrings<TErrors extends string | number = number> = Partial<Omit<Record<TErrors, string>, 0 | null>>;
7
7
 
8
- export type ValidationConfig<T> = {
9
- validator: ValueValidator<Readonly<T>>,
10
- errors: ValidationErrorsStrings,
8
+ export type ValidationConfig<T, TErrors extends string | number = ValidationErrors> = {
9
+ validator: ValueValidator<Readonly<T>, TErrors>,
10
+ errors: ValidationErrorsStrings<TErrors>,
11
11
  };
12
12
 
13
- const EmptyValidator = () => ValidationErrors.None;
13
+ const EmptyValidator = () => 0;
14
+
14
15
  export abstract class ValidatableModel<T = string> {
15
16
 
16
- private _validator: ValueValidator<Readonly<T>> = null;
17
- private _strings: ValidationErrorsStrings = null;
17
+ private _validator: ValueValidator<Readonly<T>, any> = null;
18
+ private _strings: ValidationErrorsStrings<any> = null;
18
19
 
19
20
  @observable
20
21
  private _error: string = null;
21
22
 
22
23
  private _validationError: ValidationError = null;
24
+ protected _validateOnChange = false;
23
25
 
24
- constructor(config?: ValidationConfig<T>) {
26
+ constructor() {
25
27
  makeObservable(this);
26
- this.setValidationConfig(config);
27
28
  }
28
29
 
29
30
  protected abstract get valueToValidate(): Readonly<T>;
@@ -32,12 +33,17 @@ export abstract class ValidatableModel<T = string> {
32
33
 
33
34
  get error() { return this._error; }
34
35
 
35
- public setValidationConfig(config?: ValidationConfig<T>) {
36
+ public setValidationConfig<TErrors extends string | number = ValidationErrors>(config?: ValidationConfig<T, TErrors>) {
36
37
  this._validator = config?.validator || EmptyValidator;
37
38
  this._strings = config?.errors;
38
39
  return this;
39
40
  }
40
41
 
42
+ public validateOnChange(enable = true) {
43
+ this._validateOnChange = enable;
44
+ return this;
45
+ }
46
+
41
47
  public async testValidate(value: T) {
42
48
  if (this._validator) {
43
49
  const res = await this._validator(value);
@@ -52,20 +58,22 @@ export abstract class ValidatableModel<T = string> {
52
58
  }
53
59
 
54
60
  try {
55
- const valid = await this._validator(this.valueToValidate);
56
- this._validationError = valid === ValidationErrors.None
61
+ const validationResult = await this._validator(this.valueToValidate);
62
+ this._validationError = !validationResult
57
63
  ? null
58
- : new ValidationError('Unknown error', valid);
64
+ : new ValidationError('Unknown error', validationResult);
59
65
  } catch (err) {
60
66
  this._validationError = err as ValidationError;
61
67
  }
62
68
 
63
- if (!this._validationError) {
64
- this._error = null;
65
- } else {
66
- const code = this._validationError.code;
67
- this._error = this._strings && this._strings[code];
68
- }
69
+ runInAction(() => {
70
+ if (!this._validationError) {
71
+ this._error = null;
72
+ } else {
73
+ const code = this._validationError.code;
74
+ this._error = this._strings && this._strings[code];
75
+ }
76
+ });
69
77
  return this._validationError == null;
70
78
  }
71
79
 
@@ -1,5 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './Validatable';
3
+ export * from './CommonModel';
3
4
  export * from './TextModel';
4
5
  export * from './FlagModel';
5
6
  export * from './NumberModel';