thesimplevalidation 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +158 -140
  2. package/dist/Validation.d.ts +16 -0
  3. package/dist/Validation.js +99 -0
  4. package/dist/Validation.js.map +1 -0
  5. package/{src/validation-errors-model.ts → dist/ValidationErrorsModel.d.ts} +3 -3
  6. package/dist/ValidationErrorsModel.js +2 -0
  7. package/dist/ValidationErrorsModel.js.map +1 -0
  8. package/{src/validation-model.ts → dist/ValidationModel.d.ts} +3 -3
  9. package/dist/ValidationModel.js +2 -0
  10. package/dist/ValidationModel.js.map +1 -0
  11. package/dist/ValidationPropertyResult.d.ts +4 -0
  12. package/dist/ValidationPropertyResult.js +2 -0
  13. package/dist/ValidationPropertyResult.js.map +1 -0
  14. package/dist/ValidationResult.d.ts +8 -0
  15. package/dist/ValidationResult.js +2 -0
  16. package/dist/ValidationResult.js.map +1 -0
  17. package/dist/ValidationScope.d.ts +15 -0
  18. package/dist/ValidationScope.js +95 -0
  19. package/dist/ValidationScope.js.map +1 -0
  20. package/dist/Validator.d.ts +10 -0
  21. package/dist/Validator.js +28 -0
  22. package/dist/Validator.js.map +1 -0
  23. package/{src/validator-setup.ts → dist/ValidatorSetup.d.ts} +4 -4
  24. package/dist/ValidatorSetup.js +2 -0
  25. package/dist/ValidatorSetup.js.map +1 -0
  26. package/dist/index.d.ts +8 -1
  27. package/dist/index.js +5 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/validators/boolean/BooleanValidator.d.ts +7 -0
  30. package/dist/validators/boolean/BooleanValidator.js +18 -0
  31. package/dist/validators/boolean/BooleanValidator.js.map +1 -0
  32. package/dist/validators/boolean/BooleanValidatorSetup.d.ts +4 -0
  33. package/dist/validators/boolean/BooleanValidatorSetup.js +2 -0
  34. package/dist/validators/boolean/BooleanValidatorSetup.js.map +1 -0
  35. package/dist/validators/index.d.ts +9 -0
  36. package/dist/validators/index.js +6 -0
  37. package/dist/validators/index.js.map +1 -0
  38. package/dist/validators/max/MaxValidator.d.ts +7 -0
  39. package/dist/validators/max/MaxValidator.js +26 -0
  40. package/dist/validators/max/MaxValidator.js.map +1 -0
  41. package/dist/validators/max/MaxValidatorSetup.d.ts +4 -0
  42. package/dist/validators/max/MaxValidatorSetup.js +2 -0
  43. package/dist/validators/max/MaxValidatorSetup.js.map +1 -0
  44. package/dist/validators/min/MinValidator.d.ts +7 -0
  45. package/dist/validators/min/MinValidator.js +27 -0
  46. package/dist/validators/min/MinValidator.js.map +1 -0
  47. package/dist/validators/min/MinValidatorSetup.d.ts +4 -0
  48. package/dist/validators/min/MinValidatorSetup.js +2 -0
  49. package/dist/validators/min/MinValidatorSetup.js.map +1 -0
  50. package/dist/validators/required/RequiredValidator.d.ts +7 -0
  51. package/dist/validators/required/RequiredValidator.js +21 -0
  52. package/dist/validators/required/RequiredValidator.js.map +1 -0
  53. package/dist/validators/simple/SimpleValidator.d.ts +7 -0
  54. package/dist/validators/simple/SimpleValidator.js +14 -0
  55. package/dist/validators/simple/SimpleValidator.js.map +1 -0
  56. package/dist/validators/simple/SimpleValidatorSetup.d.ts +4 -0
  57. package/dist/validators/simple/SimpleValidatorSetup.js +2 -0
  58. package/dist/validators/simple/SimpleValidatorSetup.js.map +1 -0
  59. package/package.json +13 -16
  60. package/.editorconfig +0 -11
  61. package/.travis.yml +0 -7
  62. package/.yo-rc.json +0 -9
  63. package/dist/src/index.d.ts +0 -8
  64. package/dist/src/index.js +0 -11
  65. package/dist/src/index.js.map +0 -1
  66. package/dist/src/validation-errors-model.d.ts +0 -3
  67. package/dist/src/validation-errors-model.js +0 -3
  68. package/dist/src/validation-errors-model.js.map +0 -1
  69. package/dist/src/validation-model.d.ts +0 -3
  70. package/dist/src/validation-model.js +0 -3
  71. package/dist/src/validation-model.js.map +0 -1
  72. package/dist/src/validation-property-result.d.ts +0 -4
  73. package/dist/src/validation-property-result.js +0 -3
  74. package/dist/src/validation-property-result.js.map +0 -1
  75. package/dist/src/validation-result.d.ts +0 -8
  76. package/dist/src/validation-result.js +0 -3
  77. package/dist/src/validation-result.js.map +0 -1
  78. package/dist/src/validation-scope.d.ts +0 -19
  79. package/dist/src/validation-scope.js +0 -197
  80. package/dist/src/validation-scope.js.map +0 -1
  81. package/dist/src/validator-setup.d.ts +0 -4
  82. package/dist/src/validator-setup.js +0 -3
  83. package/dist/src/validator-setup.js.map +0 -1
  84. package/dist/src/validator.d.ts +0 -8
  85. package/dist/src/validator.js +0 -68
  86. package/dist/src/validator.js.map +0 -1
  87. package/dist/src/validators/boolean/index.d.ts +0 -10
  88. package/dist/src/validators/boolean/index.js +0 -77
  89. package/dist/src/validators/boolean/index.js.map +0 -1
  90. package/dist/src/validators/index.d.ts +0 -5
  91. package/dist/src/validators/index.js +0 -13
  92. package/dist/src/validators/index.js.map +0 -1
  93. package/dist/src/validators/max/index.d.ts +0 -11
  94. package/dist/src/validators/max/index.js +0 -86
  95. package/dist/src/validators/max/index.js.map +0 -1
  96. package/dist/src/validators/min/index.d.ts +0 -11
  97. package/dist/src/validators/min/index.js +0 -87
  98. package/dist/src/validators/min/index.js.map +0 -1
  99. package/dist/src/validators/required/index.d.ts +0 -7
  100. package/dist/src/validators/required/index.js +0 -81
  101. package/dist/src/validators/required/index.js.map +0 -1
  102. package/dist/src/validators/simple/index.d.ts +0 -10
  103. package/dist/src/validators/simple/index.js +0 -73
  104. package/dist/src/validators/simple/index.js.map +0 -1
  105. package/index.ts +0 -1
  106. package/jest.config.js +0 -192
  107. package/src/index.ts +0 -9
  108. package/src/validation-property-result.ts +0 -5
  109. package/src/validation-result.ts +0 -11
  110. package/src/validation-scope.ts +0 -118
  111. package/src/validator.ts +0 -25
  112. package/src/validators/boolean/index.ts +0 -27
  113. package/src/validators/index.ts +0 -5
  114. package/src/validators/max/__tests__/index.test.ts +0 -92
  115. package/src/validators/max/index.ts +0 -34
  116. package/src/validators/min/__tests__/index.test.ts +0 -92
  117. package/src/validators/min/index.ts +0 -35
  118. package/src/validators/required/__tests__/index.test.ts +0 -229
  119. package/src/validators/required/index.ts +0 -24
  120. package/src/validators/simple/index.ts +0 -22
  121. package/thesimplevalidation.code-workspace +0 -10
  122. package/tsconfig.json +0 -23
  123. package/tslint.json +0 -18
package/README.md CHANGED
@@ -2,208 +2,209 @@
2
2
 
3
3
  The simple validation service
4
4
 
5
- [![Build Status](https://travis-ci.org/ripenko/thesimplevalidation.svg?branch=master)](https://travis-ci.org/ripenko/thesimplevalidation)
6
-
7
5
  ## Installation
6
+
8
7
  ```
9
8
  npm install --save thesimplevalidation
10
9
  ```
11
10
 
12
11
  ## Setup
13
- There are paar steps to enable validation.
14
12
 
15
- ### 1. Create a model
16
- ```typescript
17
- interface IModel {
18
- title: string;
19
- description: string;
20
- }
21
- ```
13
+ ### create validation
22
14
 
23
- ### 2. Create or use state, or something similar where we store user model values
24
- ```typescript
25
- this.model: IModel = {
26
- title: "",
27
- description: ""
28
- };
29
- ```
15
+ Create a validation using model that is passed to contructor as original model. The original model will be used to identity dirty properties.
30
16
 
31
- ### 3. Create validation model, validation errors model
32
17
  ```typescript
33
- import { ValidationModel } from "thesimplevalidation";
34
-
35
- this.validation: ValidationModel<IModel> = {
36
- title: false,
37
- description: true
38
- };
18
+ import Validation from "thesimplevalidation";
39
19
 
40
- this.validationErrors: ValidationErrorsModel<IModel> = {
41
- title: [];
42
- description: [];
43
- };
44
-
45
- this.allValidationErrors: string [] = [];
46
-
47
- this.isValid: boolean = false;
48
- ```
49
-
50
-
51
- ### 4. Creating Validation Scope
52
- ```typescript
53
- import { ValidationScope } from "thesimplevalidation";
54
-
55
- const scope = new ValidationScope<IModel>({
56
- getModel: (): IModel => this.model
20
+ const validation = new Validation({
21
+ title: "",
22
+ description: "",
57
23
  });
58
-
59
24
  ```
60
25
 
61
- ### 5. Add validators to model property(ies)
26
+ ### Add validators to model property(ies)
27
+
62
28
  There are some built-in validators like `RequiredValidator`, `MinValidator`, `MaxValidator`, `SimpleValidator`, `BooleanValidator`. You can create own by yourself. It is easy.
63
29
  So. To add validators we use validation scope method `useValidators`.
30
+
64
31
  ```typescript
65
32
  import { RequiredValidator } from "thesimplevalidation";
66
33
 
67
- this.scope.useValidators("title", new RequiredValidator());
68
-
34
+ this.validation.useValidators("title", new RequiredValidator());
69
35
  ```
70
36
 
71
37
  ### 6. Do validation
38
+
72
39
  ```typescript
73
- const result: IValidationResult<IModel> = await this.scope.isValid();
74
- console.log(result.isValid, result);
40
+ const result = await this.scope.isValid({
41
+ title: "",
42
+ description: "",
43
+ });
44
+
45
+ console.log(result.isValid, result);
75
46
  // -> false, { isValid: false, properties: { title: { isValid: false, errors: [] }, description: { isValid: true, errors: [] } }, errors: [] }
76
47
  ```
77
48
 
78
49
  ## Usage
79
50
 
80
- ### ValidationScope
81
- This class is main point to define validation. Possible to define more than one scope in the form. As you wish.
51
+ ### Validation
52
+
53
+ This class is main point to define validation. Possible to define more than one instance in the form. As you wish.
54
+
82
55
  ```typescript
83
- const scope = new ValidationScope<IModel>({
84
- getModel: (): IModel => this.model
85
- onValidationChanged: async (result: IValidationResult<TModel>): Promise<void> => {
86
- const properties: Array<keyof TModel> = keys(result.properties) as Array<keyof TModel>;
87
- const validation: ValidationModel<TModel> = {} as ValidationModel<TModel>;
88
- const validationErrors: ValidationErrorsModel<TModel> = {} as ValidationErrorsModel<TModel>;
89
-
90
- for (const property of properties) {
91
- if (!result.properties.hasOwnProperty(property)) continue;
92
-
93
- validation[property] = result.properties[property].isValid;
94
- validationErrors[property] = result.properties[property].errors;
95
- }
96
-
97
- this.isValid = result.isValid;
98
- this.validation = validation;
99
- this.validationErrors = validationErrors;
100
- this.allValidationErrors = result.errors;
101
- }
102
- });
56
+ const validation = new Validation<Model>({
57
+ firstName: "",
58
+ lastName: "",
59
+ })
60
+ .useValidators("firstName", new RequiredValidator())
61
+ .useValidators("lastName", new RequiredValidator());
103
62
  ```
104
- `getModel` is invoked on validation by method `isValid`.
105
- `onValidationChanged` Optional. To handle validation result. It is invoked before `isValid` method is completed.
63
+
64
+ The value that is passed to constructor is used as initial model or original model.
106
65
 
107
66
  ### `isValid`
67
+
108
68
  Validates the whole model.
69
+
109
70
  ```typescript
110
- const result: IValidationResult<IModel> = await this.scope.isValid();
71
+ const model = {
72
+ firstName: "Alexey",
73
+ lastName: "",
74
+ };
75
+
76
+ const result: ValidationResult<Model> = await this.validation.isValid(model);
111
77
  console.log(result.isValid); // -> false
112
78
  ```
113
79
 
114
80
  #### `isPropertyValid`
81
+
115
82
  Validates only a specific property.
83
+
116
84
  ```typescript
117
- const propertyResult: IValidationPropertyResult = await this.scope.isPropertyValid("description");
85
+ const propertyResult: ValidationPropertyResult =
86
+ await this.validation.isPropertyValid(model, "firstName");
118
87
  console.log(propertyResult.isValid); // -> false
119
88
  ```
120
89
 
121
90
  #### `useValidators`
91
+
122
92
  Use this method to set validators for property.
93
+
123
94
  ```typescript
124
- this.scope.useValidators(
125
- "title", // property
126
- new RequiredValidator(),
127
- new MaxValidator({ maxValue: () => 10 }),
128
- // add more validators if you need
95
+ this.validation.useValidators(
96
+ "title", // property
97
+ new RequiredValidator(),
98
+ new MaxValidator({ maxValue: () => 10 })
99
+ // add more validators if you need
129
100
  );
130
101
  ```
131
102
 
132
103
  #### `useOriginal`
133
- You have built-in ability to check if the property has been changed or not. `isDirty`.
104
+
105
+ You have built-in ability to check if the property has been changed or not. `isDirty`.
134
106
  To do it scope save a deep cloned copy of the model on init. When we invoke `isDirty`, then `isDirty` method compares value to saved copy.
135
107
  `useOriginal` resets saved cloned copy of model.
108
+
136
109
  ```typescript
137
- this.scope.useOriginal(newModel);
110
+ this.validation.useOriginal({
111
+ firstName: "Alexey",
112
+ lastName: "Ripenko",
113
+ });
138
114
  ```
139
115
 
140
116
  #### `isPropertyDirty`
117
+
141
118
  The method of the validation scope allows to check if property has been changed (dirty).
119
+
142
120
  ```typescript
143
- this.model.title = "New Title";
144
- let isTitleDirty: boolean = this.scope.isPropertyDirty("title");
145
- console.log(isTitleDirty); // -> true
121
+ this.model.firstName = "Mike";
122
+ let isFirstNameDirty: boolean = this.validation.isPropertyDirty(
123
+ model,
124
+ "firstName"
125
+ );
126
+ console.log(isFirstNameDirty); // -> true
146
127
 
147
- this.scope.useOriginal(this.model);
148
- isTitleDirty = this.scope.isPropertyDirty("title");
149
- console.log(isTitleDirty); // -> false
128
+ this.validation.useOriginal(this.model);
129
+ isFirstNameDirty = this.validation.isPropertyDirty(model, "firstName");
130
+ console.log(isFirstNameDirty); // -> false
150
131
  ```
151
132
 
152
133
  This method has optional `key` parameter. It uses to use nested value if property is object with nested object-properties. Example `someProperty.someNestedProperty.key`, `arrayProperty.key`.
153
134
 
154
-
155
135
  #### `getOriginalProperty`
136
+
156
137
  Gets property from saved cloned model.
138
+
157
139
  ```typescript
158
- const originalTitle = this.scope.getOriginalProperty("title");
140
+ const originalFirstName = this.validation.getOriginalProperty("firstName");
159
141
  ```
160
142
 
161
143
  #### `isDirty`
144
+
162
145
  Checks if model or model properties have been changed (dirty).
163
146
 
164
147
  Checks the whole model
148
+
165
149
  ```typescript
166
- this.scope.isDirty();
150
+ this.validation.isDirty(model);
167
151
  ```
168
- or checks only `title` property
152
+
153
+ or checks only `firstName` property
154
+
169
155
  ```typescript
170
- this.scope.isDirty("title");
156
+ this.validation.isDirty(model, "firstName");
171
157
  ```
158
+
172
159
  or checks multiple properties
160
+
173
161
  ```typescript
174
- this.scope.isDirty("title", "description");
162
+ this.scope.isDirty(model, "firstName", "lastName");
175
163
  ```
176
164
 
177
165
  ### Validators
166
+
178
167
  You can create own validator using the followed template:
168
+
179
169
  ```typescript
180
- import { IValidationPropertyResult, IValidatorSetup, Validator } from "thesimplevalidation";
170
+ import {
171
+ ValidationPropertyResult,
172
+ ValidatorSetup,
173
+ Validator,
174
+ } from "thesimplevalidation";
181
175
 
182
176
  // if you need to pass extra data you can put here.
183
- export interface IMyValidatorSetup<TModel, K extends keyof TModel> extends IValidatorSetup<TModel, K> {
184
- extraParam: () => number;
177
+ export type MyValidatorSetup<TModel, K extends keyof TModel> = ValidatorSetup<
178
+ TModel,
179
+ K
180
+ > & { extraParam: () => number };
181
+
182
+ export class MyValidator<TModel, K extends keyof TModel> extends Validator<
183
+ TModel,
184
+ K,
185
+ MyValidatorSetup<TModel, K>
186
+ > {
187
+ constructor(setup: MyValidatorSetup<TModel, K>) {
188
+ super(setup);
189
+ }
190
+
191
+ public async isValidInternal(
192
+ _value: TModel[K]
193
+ ): Promise<ValidationPropertyResult> {
194
+ let isValid: boolean = true;
195
+
196
+ //... add validation core here to set isValid
197
+
198
+ return {
199
+ isValid: isValid,
200
+ errors: [], // You can add errors here, or use `setup.getErrors` method
201
+ };
202
+ }
185
203
  }
186
-
187
- export class MyValidator<TModel, K extends keyof TModel> extends Validator<TModel, K, IMyValidatorSetup<TModel, K>> {
188
- constructor(setup: IMyValidatorSetup<TModel, K>) {
189
- super(setup);
190
- }
191
-
192
- public async isValidInternal(_value: TModel[K]): Promise<IValidationPropertyResult> {
193
- let isValid: boolean = true;
194
-
195
- //... add validation core here to set isValid
196
-
197
- return {
198
- isValid: isValid,
199
- errors: [] // You can add errors here, or use `setup.getErrors` method
200
- };
201
- }
202
- }
203
-
204
204
  ```
205
205
 
206
- #### `IMyValidatorSetup<TModel, K>`
206
+ #### `MyValidatorSetup<TModel, K>`
207
+
207
208
  The base options of validators.
208
209
 
209
210
  `isDisabled?: (value: TModel[K]) => boolean;` is used to disable validator based on some logic-function.
@@ -212,84 +213,101 @@ Could be nice if validation logic is depended on some values, logic, etc...
212
213
  `getErrors?: (value: TModel[K]) => string[];` is used to define error messages.
213
214
 
214
215
  #### RequiredValidator
216
+
215
217
  Validates property against `""`, `null`, `undefined`, `0`, array.`length`.
216
218
 
217
219
  #### MinValidator
218
- Validates the minimum value of property.
219
220
 
220
- Property value is a string then the validator checks the string length.
221
+ Validates the minimum value of property.
222
+
223
+ Property value is a string then the validator checks the string length.
221
224
  If an array then the validator checks the array length.
222
225
  If a number then the validator validate against min value.
223
226
 
224
227
  ```typescript
225
228
  new MinValidator({
226
- minValue: () => 10
229
+ minValue: () => 10,
227
230
  });
228
231
  ```
229
232
 
230
233
  #### MaxValidator
231
- Validates the maximum value of property.
232
234
 
233
- Property value is a string then the validator checks the string length.
235
+ Validates the maximum value of property.
236
+
237
+ Property value is a string then the validator checks the string length.
234
238
  If an array then the validator checks the array length.
235
239
  If a number then the validator validate against max value.
236
240
 
237
241
  ```typescript
238
242
  new MaxValidator({
239
- maxValue: () => 255
243
+ maxValue: () => 255,
240
244
  });
241
245
  ```
242
246
 
243
247
  #### BooleanValidator
248
+
244
249
  Validates if the model boolean property value is the same if some boolean value
250
+
245
251
  ```typescript
246
252
  new MaxValidator({
247
- target: () => true
253
+ target: () => true,
248
254
  });
249
255
  ```
250
256
 
251
257
  #### SimpleValidator
258
+
252
259
  The simpliest validator that option `getValidation` boolean value will be used as isValid of validation. The model property value is not used.
253
260
  See implementation:
261
+
254
262
  ```typescript
255
- export interface ISimpleValidatorSetup<TModel, K extends keyof TModel> extends IValidatorSetup<TModel, K> {
256
- getValidation: () => boolean;
263
+ export interface SimpleValidatorSetup<TModel, K extends keyof TModel>
264
+ extends ValidatorSetup<TModel, K> {
265
+ getValidation: () => boolean;
257
266
  }
258
267
 
259
- export class SimpleValidator<TModel, K extends keyof TModel> extends Validator<TModel, K, ISimpleValidatorSetup<TModel, K>> {
260
- constructor(setup: ISimpleValidatorSetup<TModel, K>) {
261
- super(setup);
262
- }
263
-
264
- public async isValidInternal(_value: TModel[K]): Promise<IValidationPropertyResult> {
265
- const isValid: boolean = this.setup.getValidation();
266
-
267
- return {
268
- isValid: isValid,
269
- errors: []
270
- };
271
- }
268
+ export class SimpleValidator<TModel, K extends keyof TModel> extends Validator<
269
+ TModel,
270
+ K,
271
+ SimpleValidatorSetup<TModel, K>
272
+ > {
273
+ constructor(setup: SimpleValidatorSetup<TModel, K>) {
274
+ super(setup);
275
+ }
276
+
277
+ public async isValidInternal(
278
+ _value: TModel[K]
279
+ ): Promise<ValidationPropertyResult> {
280
+ const isValid: boolean = this.setup.getValidation();
281
+
282
+ return {
283
+ isValid: isValid,
284
+ errors: [],
285
+ };
286
+ }
272
287
  }
273
288
  ```
274
289
 
275
290
  Example:
291
+
276
292
  ```typescript
277
293
  new SimpleValidator({
278
- getValidation: () => true
294
+ getValidation: () => true,
279
295
  });
280
296
  // -> isValid = true
281
297
  ```
298
+
282
299
  or
300
+
283
301
  ```typescript
284
302
  new SimpleValidator({
285
- getValidation: () => false
303
+ getValidation: () => false,
286
304
  });
287
305
  // -> isValid = false
288
306
  ```
289
307
 
290
-
291
308
  ## Credits
292
- [Alexey Ripenko](http://ripenko.ru/), [GitHub](https://github.com/ripenko/)
309
+
310
+ [Alexey Ripenko](https://www.linkedin.com/in/ripenko/), [GitHub](https://github.com/ripenko/)
293
311
 
294
312
  ## License
295
313
 
@@ -0,0 +1,16 @@
1
+ import { ValidationPropertyResult } from "./ValidationPropertyResult";
2
+ import { ValidationResult } from "./ValidationResult";
3
+ import { Validator } from "./Validator";
4
+ export declare class Validation<TModel extends {}> {
5
+ private originalModel;
6
+ private modelInfo;
7
+ constructor(originalModel: TModel);
8
+ useOriginal: (model: TModel) => Validation<TModel>;
9
+ useNoValidators: () => Validation<TModel>;
10
+ useValidators: <K extends keyof TModel>(key: K, ...validators: Array<Validator<TModel, K>>) => Validation<TModel>;
11
+ isPropertyDirty: (model: TModel, field: keyof TModel, key?: string | null) => boolean;
12
+ getOriginalProperty: <K extends keyof TModel>(field: K) => TModel[K];
13
+ isDirty: (model: TModel, ...fields: Array<keyof TModel>) => boolean;
14
+ isPropertyValid: <K extends keyof TModel>(model: TModel, field: K) => Promise<ValidationPropertyResult>;
15
+ isValid: (model: TModel, ...fields: Array<keyof TModel>) => Promise<ValidationResult<TModel>>;
16
+ }
@@ -0,0 +1,99 @@
1
+ import get from "lodash.get";
2
+ import isEqual from "lodash.isequal";
3
+ export class Validation {
4
+ constructor(originalModel) {
5
+ this.useOriginal = (model) => {
6
+ this.originalModel = structuredClone(model);
7
+ return this;
8
+ };
9
+ this.useNoValidators = () => {
10
+ this.modelInfo = {};
11
+ return this;
12
+ };
13
+ this.useValidators = (key, ...validators) => {
14
+ this.modelInfo[key] = {
15
+ validators: validators,
16
+ };
17
+ return this;
18
+ };
19
+ this.isPropertyDirty = (model, field, key = null) => {
20
+ const originalField = this.originalModel[field];
21
+ const modelField = model[field];
22
+ if (Array.isArray(originalField) && Array.isArray(modelField)) {
23
+ if (originalField.length !== modelField.length)
24
+ return true;
25
+ for (let index = 0; index < originalField.length; index++) {
26
+ if (originalField[index] === modelField[index])
27
+ continue;
28
+ if (key == null)
29
+ return true;
30
+ if (get(originalField[index], key) !== get(modelField[index], key))
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+ if (key == null)
36
+ return !isEqual(this.originalModel[field], model[field]);
37
+ return get(this.originalModel[field], key) !== get(model[field], key);
38
+ };
39
+ this.getOriginalProperty = (field) => {
40
+ return this.originalModel[field];
41
+ };
42
+ this.isDirty = (model, ...fields) => {
43
+ for (const property in this.originalModel) {
44
+ if (!this.originalModel.hasOwnProperty(property))
45
+ continue;
46
+ if (fields && fields.length > 0) {
47
+ if (!fields.some((x) => x === property))
48
+ continue;
49
+ }
50
+ if (this.isPropertyDirty(model, property))
51
+ return true;
52
+ }
53
+ return false;
54
+ };
55
+ this.isPropertyValid = async (model, field) => {
56
+ if (this.modelInfo[field] &&
57
+ this.modelInfo[field].validators &&
58
+ this.modelInfo[field].validators) {
59
+ let isValid = true;
60
+ let errors = [];
61
+ const value = model[field];
62
+ for (const validator of this.modelInfo[field].validators) {
63
+ const validatorResult = await validator.isValid(value, model, field);
64
+ isValid = isValid && validatorResult.isValid;
65
+ if (!validatorResult.isValid)
66
+ errors = [...errors, ...validatorResult.errors];
67
+ }
68
+ return {
69
+ isValid: isValid,
70
+ errors: errors,
71
+ };
72
+ }
73
+ return {
74
+ isValid: true,
75
+ errors: [],
76
+ };
77
+ };
78
+ this.isValid = async (model, ...fields) => {
79
+ model = model ?? {};
80
+ const properties = (fields == null || fields.length === 0 ? Object.keys(model) : fields);
81
+ const result = {
82
+ isValid: true,
83
+ errors: [],
84
+ properties: {},
85
+ };
86
+ for (const property of properties) {
87
+ const propertyValidationResult = await this.isPropertyValid(model, property);
88
+ result.isValid = result.isValid && propertyValidationResult.isValid;
89
+ result.properties[property] = propertyValidationResult;
90
+ if (!propertyValidationResult.isValid)
91
+ result.errors = [...result.errors, ...propertyValidationResult.errors];
92
+ }
93
+ return result;
94
+ };
95
+ this.originalModel = structuredClone(originalModel);
96
+ this.modelInfo = {};
97
+ }
98
+ }
99
+ //# sourceMappingURL=Validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Validation.js","sourceRoot":"","sources":["../src/Validation.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- export type ValidationErrorsModel<TModel> = {
2
- [k in keyof TModel]: string[];
3
- };
1
+ export type ValidationErrorsModel<TModel> = {
2
+ [k in keyof TModel]: string[];
3
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ValidationErrorsModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationErrorsModel.js","sourceRoot":"","sources":["../src/ValidationErrorsModel.ts"],"names":[],"mappings":""}
@@ -1,3 +1,3 @@
1
- export type ValidationModel<TModel> = {
2
- [K in keyof TModel]: boolean;
3
- };
1
+ export type ValidationModel<TModel> = {
2
+ [K in keyof TModel]: boolean;
3
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ValidationModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationModel.js","sourceRoot":"","sources":["../src/ValidationModel.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export type ValidationPropertyResult = {
2
+ isValid: boolean;
3
+ errors: string[];
4
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ValidationPropertyResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationPropertyResult.js","sourceRoot":"","sources":["../src/ValidationPropertyResult.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { ValidationPropertyResult } from "./ValidationPropertyResult";
2
+ export type ValidationResult<TModel> = {
3
+ isValid: boolean;
4
+ properties: {
5
+ [K in keyof TModel]: ValidationPropertyResult;
6
+ };
7
+ errors: string[];
8
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ValidationResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationResult.js","sourceRoot":"","sources":["../src/ValidationResult.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { ValidationPropertyResult } from "./ValidationPropertyResult";
2
+ import { ValidationResult } from "./ValidationResult";
3
+ import { Validator } from "./Validator";
4
+ export declare class ValidationScope<TModel extends {}> {
5
+ private originalModel;
6
+ private modelInfo;
7
+ constructor(originalModel: TModel);
8
+ useOriginal: (model: TModel) => ValidationScope<TModel>;
9
+ useValidators: <K extends keyof TModel>(key: K, ...validators: Array<Validator<TModel, K>>) => ValidationScope<TModel>;
10
+ isPropertyDirty: (model: TModel, field: keyof TModel, key?: string | null) => boolean;
11
+ getOriginalProperty: <K extends keyof TModel>(field: K) => TModel[K];
12
+ isDirty: (model: TModel, ...fields: Array<keyof TModel>) => boolean;
13
+ isPropertyValid: <K extends keyof TModel>(model: TModel, field: K) => Promise<ValidationPropertyResult>;
14
+ isValid: (model: TModel, ...fields: Array<keyof TModel>) => Promise<ValidationResult<TModel>>;
15
+ }