nox-validation 1.0.1 → 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.
- package/README.md +13 -2
- package/lib/constant.js +100 -0
- package/lib/helpers.js +14 -18
- package/lib/validate.js +217 -202
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,12 +11,15 @@ npm install nox-validation
|
|
|
11
11
|
## Library Exports
|
|
12
12
|
|
|
13
13
|
### **Validation Functions:**
|
|
14
|
+
|
|
14
15
|
- `validate` - The core function for validating data.
|
|
15
16
|
|
|
16
17
|
### **Constants:**
|
|
18
|
+
|
|
17
19
|
- `CONSTANTS` - A collection of predefined constants (likely including data types, error messages, validation rules, etc.).
|
|
18
20
|
|
|
19
21
|
### **Helper Functions (`HELPERS`):**
|
|
22
|
+
|
|
20
23
|
- `validateSingleField` - Validates a single field against defined rules.
|
|
21
24
|
- `validateType` - Performs type checks for data validation.
|
|
22
25
|
- `fieldsMapping` - Groups fields by `schemaId` for structured access.
|
|
@@ -26,7 +29,6 @@ npm install nox-validation
|
|
|
26
29
|
|
|
27
30
|
## Usage
|
|
28
31
|
|
|
29
|
-
|
|
30
32
|
```javascript
|
|
31
33
|
const { validate, helpers } = require("nox-validation");
|
|
32
34
|
|
|
@@ -91,10 +93,10 @@ const schema = [
|
|
|
91
93
|
},
|
|
92
94
|
},
|
|
93
95
|
];
|
|
94
|
-
|
|
95
96
|
```
|
|
96
97
|
|
|
97
98
|
#### When `isSeparatedFields` is `true`
|
|
99
|
+
|
|
98
100
|
```javascript
|
|
99
101
|
const result = validate({
|
|
100
102
|
formData: {
|
|
@@ -109,10 +111,12 @@ const result = validate({
|
|
|
109
111
|
abortEarly: false,
|
|
110
112
|
byPassKeys: [],
|
|
111
113
|
apiVersion: "v1",
|
|
114
|
+
language: "nl",
|
|
112
115
|
});
|
|
113
116
|
```
|
|
114
117
|
|
|
115
118
|
#### When `isSeparatedFields` is `false`
|
|
119
|
+
|
|
116
120
|
```javascript
|
|
117
121
|
const result = validate({
|
|
118
122
|
formData: {
|
|
@@ -127,10 +131,12 @@ const result = validate({
|
|
|
127
131
|
abortEarly: false,
|
|
128
132
|
byPassKeys: [],
|
|
129
133
|
apiVersion: "v1",
|
|
134
|
+
language: "nl",
|
|
130
135
|
});
|
|
131
136
|
```
|
|
132
137
|
|
|
133
138
|
#### Output Example:
|
|
139
|
+
|
|
134
140
|
```javascript
|
|
135
141
|
{
|
|
136
142
|
status: true, // Validation passed
|
|
@@ -190,6 +196,11 @@ const result = validate({
|
|
|
190
196
|
- Specifies the API version (`"v1"` or `"v2"`).
|
|
191
197
|
- Helps in maintaining compatibility and version control.
|
|
192
198
|
|
|
199
|
+
#### `language` (String)
|
|
200
|
+
|
|
201
|
+
- Specifies the locale language (`"nl"` or `"en"`).
|
|
202
|
+
- Determines the locale for validation messages.
|
|
203
|
+
|
|
193
204
|
## Result
|
|
194
205
|
|
|
195
206
|
The `validate` function returns an object with two keys:
|
package/lib/constant.js
CHANGED
|
@@ -151,6 +151,104 @@ const API_VERSION = Object.freeze({
|
|
|
151
151
|
|
|
152
152
|
const API_VERSIONS = Object.freeze(Object.values(API_VERSION));
|
|
153
153
|
|
|
154
|
+
const LANGUAGES = Object.freeze({
|
|
155
|
+
en: "en",
|
|
156
|
+
nl: "nl",
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const LOCALE_NL_MESSAGES = Object.freeze({
|
|
160
|
+
INVALID_VALUE: `{field} bevat een ongeldige waarde.`,
|
|
161
|
+
EMPTY: `{field} moet leeg zijn.`,
|
|
162
|
+
NOT_EMPTY: `{field} mag niet leeg zijn.`,
|
|
163
|
+
ONE_OF: `{field} moet een van de volgende waarden zijn: {value}.`,
|
|
164
|
+
NOT_ONE_OF: `{field} mag niet een van de volgende waarden zijn: {value}.`,
|
|
165
|
+
REQUIRED: `{field} is verplicht.`,
|
|
166
|
+
OPTIONAL: `{field} is optioneel.`,
|
|
167
|
+
NOT_NULLABLE: `{field} mag niet null zijn.`,
|
|
168
|
+
INVALID_TYPE: "{field} bevat een ongeldig invoertype. Alleen {type} is toegestaan.",
|
|
169
|
+
NOT_ALLOWED_FIELD: `{field} is niet toegestaan.`,
|
|
170
|
+
COMPARE: `{field} komt niet overeen met de verwachte waarde.`,
|
|
171
|
+
RULES_COMPARE: `{field} voldoet niet aan de vergelijkingsregels.`,
|
|
172
|
+
ALLOW: `{field} bevat alleen toegestane tekens.`,
|
|
173
|
+
NOT_ALLOWED: `{field} bevat niet-toegestane tekens.`,
|
|
174
|
+
REGEX_MATCH: `{field} heeft een ongeldig formaat.`,
|
|
175
|
+
REGEX_START_WITH: `{field} moet beginnen met {value}.`,
|
|
176
|
+
REGEX_ENDS_WITH: `{field} moet eindigen op {value}.`,
|
|
177
|
+
REGEX_CONTAINS: `{field} moet {value} bevatten.`,
|
|
178
|
+
REGEX_EXACT: `{field} moet exact {value} zijn.`,
|
|
179
|
+
REGEX_NOT_START_WITH: `{field} mag niet beginnen met {value}.`,
|
|
180
|
+
REGEX_NOT_ENDS_WITH: `{field} mag niet eindigen op {value}.`,
|
|
181
|
+
REGEX_NOT_CONTAINS: `{field} mag {value} niet bevatten.`,
|
|
182
|
+
MIN_STRING: `{field} moet minstens {min} tekens lang zijn.`,
|
|
183
|
+
MAX_STRING: `{field} mag maximaal {max} tekens lang zijn.`,
|
|
184
|
+
MIN_NUMBER: `{field} moet minstens {min} zijn.`,
|
|
185
|
+
MAX_NUMBER: `{field} mag maximaal {max} zijn.`,
|
|
186
|
+
AND: "{field} moet een van {value} zijn.",
|
|
187
|
+
OR: "{field} moet een van {value} zijn.",
|
|
188
|
+
EQUAL: "{field} moet gelijk zijn aan {value}.",
|
|
189
|
+
NOT_EQUAL: "{field} mag niet gelijk zijn aan {value}.",
|
|
190
|
+
LESS_THAN: "{field} moet kleiner zijn dan {value}.",
|
|
191
|
+
LESS_THAN_EQUAL: "{field} moet kleiner dan of gelijk zijn aan {value}.",
|
|
192
|
+
GREATER_THAN: "{field} moet groter zijn dan {value}.",
|
|
193
|
+
GREATER_THAN_EQUAL: "{field} moet groter dan of gelijk zijn aan {value}.",
|
|
194
|
+
IN: "{field} moet een van de volgende waarden zijn: {value}.",
|
|
195
|
+
NOT_IN: "{field} mag geen van de volgende waarden bevatten: {value}.",
|
|
196
|
+
EXISTS: "{field} moet bestaan.",
|
|
197
|
+
TYPE: "{field} moet van type {value} zijn.",
|
|
198
|
+
MOD: "{field} moet een restwaarde van {value[1]} hebben wanneer gedeeld door {value[0]}.",
|
|
199
|
+
ALL: "{field} moet alle van de volgende waarden bevatten: {value}.",
|
|
200
|
+
SIZE: "{field} moet een grootte van {value} hebben.",
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const LOCALE_EN_MESSAGES = Object.freeze({
|
|
204
|
+
INVALID_VALUE: `{field} contains invalid value.`,
|
|
205
|
+
EMPTY: `{field} should be empty.`,
|
|
206
|
+
NOT_EMPTY: `{field} should not be empty.`,
|
|
207
|
+
ONE_OF: `{field} should be one of the following: {value}.`,
|
|
208
|
+
NOT_ONE_OF: `{field} should not be one of the following: {value}.`,
|
|
209
|
+
REQUIRED: `{field} is required.`,
|
|
210
|
+
OPTIONAL: `{field} is optional.`,
|
|
211
|
+
NOT_NULLABLE: `{field} can not be null.`,
|
|
212
|
+
INVALID_TYPE: "{field} contains invalid input type. Only {type} is allowed.",
|
|
213
|
+
NOT_ALLOWED_FIELD: `{field} is not allowed.`,
|
|
214
|
+
COMPARE: `{field} does not match the expected value.`,
|
|
215
|
+
RULES_COMPARE: `{field} does not meet the comparison rules.`,
|
|
216
|
+
ALLOW: `{field} contains allowed characters only.`,
|
|
217
|
+
NOT_ALLOWED: `{field} contains disallowed characters.`,
|
|
218
|
+
REGEX_MATCH: `{field} format is invalid.`,
|
|
219
|
+
REGEX_START_WITH: `{field} should start with {value}.`,
|
|
220
|
+
REGEX_ENDS_WITH: `{field} should end with {value}.`,
|
|
221
|
+
REGEX_CONTAINS: `{field} should contain {value}.`,
|
|
222
|
+
REGEX_EXACT: `{field} should be exactly {value}.`,
|
|
223
|
+
REGEX_NOT_START_WITH: `{field} should not be start with {value}.`,
|
|
224
|
+
REGEX_NOT_ENDS_WITH: `{field} should not be ends with {value}.`,
|
|
225
|
+
REGEX_NOT_CONTAINS: `{field} should not contains {value}.`,
|
|
226
|
+
MIN_STRING: `{field} must be at least {min} characters long.`,
|
|
227
|
+
MAX_STRING: `{field} must be at most {max} characters long.`,
|
|
228
|
+
MIN_NUMBER: `{field} must be at least {min}.`,
|
|
229
|
+
MAX_NUMBER: `{field} must be at most {max}.`,
|
|
230
|
+
AND: "{field} must be any of {value}",
|
|
231
|
+
OR: "{field} must be any of {value}",
|
|
232
|
+
EQUAL: "{field} must be equal to {value}",
|
|
233
|
+
NOT_EQUAL: "{field} must not be equal to {value}",
|
|
234
|
+
LESS_THAN: "{field} must be less than {value}",
|
|
235
|
+
LESS_THAN_EQUAL: "{field} must be less than or equal to {value}",
|
|
236
|
+
GREATER_THAN: "{field} must be greater than {value}",
|
|
237
|
+
GREATER_THAN_EQUAL: "{field} must be greater than or equal to {value}",
|
|
238
|
+
IN: "{field} must be one of the following: {value}",
|
|
239
|
+
NOT_IN: "{field} must not contain any of these values: {value}",
|
|
240
|
+
EXISTS: "{field} must exist",
|
|
241
|
+
TYPE: "{field} must be of type {value}",
|
|
242
|
+
MOD: "{field} must have a remainder of {value[1]} when divided by {value[0]}",
|
|
243
|
+
ALL: "{field} must contain all of the following values: {value}",
|
|
244
|
+
SIZE: "{field} must have a size of {value}",
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const LOCALE_MESSAGES = Object.freeze({
|
|
248
|
+
[LANGUAGES.en]:LOCALE_EN_MESSAGES,
|
|
249
|
+
[LANGUAGES.nl]:LOCALE_NL_MESSAGES
|
|
250
|
+
})
|
|
251
|
+
|
|
154
252
|
module.exports = {
|
|
155
253
|
dataTypes,
|
|
156
254
|
operatorTypes,
|
|
@@ -162,4 +260,6 @@ module.exports = {
|
|
|
162
260
|
interfaces,
|
|
163
261
|
API_VERSIONS,
|
|
164
262
|
API_VERSION,
|
|
263
|
+
LANGUAGES,
|
|
264
|
+
LOCALE_MESSAGES
|
|
165
265
|
};
|
package/lib/helpers.js
CHANGED
|
@@ -293,12 +293,7 @@ const generateRelationalFieldV1 = (key = "", collectionFields = [], relationType
|
|
|
293
293
|
return [
|
|
294
294
|
generateField("collection", "collection", constants.types.STRING, constants.types.STRING),
|
|
295
295
|
generateField("sort", "sort", constants.types.NUMBER, constants.types.NUMBER),
|
|
296
|
-
generateField(
|
|
297
|
-
"item",
|
|
298
|
-
"item",
|
|
299
|
-
constants.types.OBJECT_ID,
|
|
300
|
-
constants.types.OBJECT_ID,
|
|
301
|
-
),
|
|
296
|
+
generateField("item", "item", constants.types.OBJECT_ID, constants.types.OBJECT_ID),
|
|
302
297
|
];
|
|
303
298
|
} else {
|
|
304
299
|
return [];
|
|
@@ -556,16 +551,15 @@ const getCachedOrFetchFields = (schemaId, allFields, relational_fields) => {
|
|
|
556
551
|
|
|
557
552
|
const getChildFields = (relationDetail, allFields, relational_fields, isTranslation) => {
|
|
558
553
|
let key = isTranslation
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
554
|
+
? [
|
|
555
|
+
...(Array.isArray(relationDetail.junction_collection)
|
|
556
|
+
? relationDetail.junction_collection
|
|
557
|
+
: [relationDetail.junction_collection]),
|
|
558
|
+
...(Array.isArray(relationDetail.foreign_collection)
|
|
559
|
+
? relationDetail.foreign_collection
|
|
560
|
+
: [relationDetail.foreign_collection]),
|
|
561
|
+
]
|
|
562
|
+
: relationDetail.foreign_collection;
|
|
569
563
|
|
|
570
564
|
const isMultiple = Array.isArray(key);
|
|
571
565
|
|
|
@@ -647,8 +641,9 @@ const buildNestedStructure = (
|
|
|
647
641
|
},
|
|
648
642
|
validations:
|
|
649
643
|
item?.meta?.validations?.rules?.length > 0
|
|
650
|
-
? generateModifiedRules(item?.meta,
|
|
644
|
+
? generateModifiedRules(item?.meta, item?.meta?.validations?.validation_msg)
|
|
651
645
|
: [],
|
|
646
|
+
custom_error_message: item?.meta?.validations?.validation_msg,
|
|
652
647
|
children:
|
|
653
648
|
childFields?.length > 0
|
|
654
649
|
? apiVersion === constants.API_VERSION.V1 &&
|
|
@@ -826,13 +821,14 @@ const generateFieldCompareRules = (rule) => {
|
|
|
826
821
|
return modifiedRule;
|
|
827
822
|
};
|
|
828
823
|
|
|
829
|
-
const generateModifiedRules = (meta) => {
|
|
824
|
+
const generateModifiedRules = (meta,custom_message) => {
|
|
830
825
|
return meta?.validations?.rules?.map((rule, index) => {
|
|
831
826
|
let modifiedRule = {
|
|
832
827
|
identifier: String(index),
|
|
833
828
|
case: constants.rulesTypes.RULES_COMPARE,
|
|
834
829
|
value: [],
|
|
835
830
|
options: {},
|
|
831
|
+
custom_message
|
|
836
832
|
};
|
|
837
833
|
switch (rule.rule) {
|
|
838
834
|
case "contains":
|
package/lib/validate.js
CHANGED
|
@@ -65,14 +65,11 @@ const typeChecks = {
|
|
|
65
65
|
},
|
|
66
66
|
|
|
67
67
|
[constants.types.TIME]: (val) =>
|
|
68
|
-
typeof val === "string" &&
|
|
69
|
-
/^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/.test(val),
|
|
68
|
+
typeof val === "string" && /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/.test(val),
|
|
70
69
|
[constants.types.STRING]: (val) => typeof val === "string",
|
|
71
|
-
[constants.types.OBJECT]: (val) =>
|
|
72
|
-
typeof val === "object" && val !== null && !Array.isArray(val),
|
|
70
|
+
[constants.types.OBJECT]: (val) => typeof val === "object" && val !== null && !Array.isArray(val),
|
|
73
71
|
[constants.types.ARRAY]: (val) => Array.isArray(val),
|
|
74
|
-
[constants.types.OBJECT_ID]: (val) =>
|
|
75
|
-
typeof val === "string" && /^[0-9a-fA-F]{24}$/.test(val),
|
|
72
|
+
[constants.types.OBJECT_ID]: (val) => typeof val === "string" && /^[0-9a-fA-F]{24}$/.test(val),
|
|
76
73
|
[constants.types.MIXED]: (val) => (val ? true : false),
|
|
77
74
|
[constants.types.BUFFER]: (val) => val instanceof Buffer,
|
|
78
75
|
[constants.types.ALIAS]: (val) => (val ? true : false),
|
|
@@ -85,6 +82,8 @@ const handleMinMaxValidation = (
|
|
|
85
82
|
field,
|
|
86
83
|
addError,
|
|
87
84
|
currentPath,
|
|
85
|
+
error_messages,
|
|
86
|
+
custom_message
|
|
88
87
|
) => {
|
|
89
88
|
let message = "";
|
|
90
89
|
const fieldLabel = formatLabel(field.display_label);
|
|
@@ -95,19 +94,15 @@ const handleMinMaxValidation = (
|
|
|
95
94
|
typeChecks[constants.types.STRING](fieldValue) &&
|
|
96
95
|
fieldValue?.length < ruleValue[0]
|
|
97
96
|
) {
|
|
98
|
-
message =
|
|
99
|
-
|
|
100
|
-
fieldLabel,
|
|
101
|
-
).replace(`{min}`, ruleValue[0]);
|
|
97
|
+
message = custom_message ?? error_messages.MIN_STRING;
|
|
98
|
+
message = message?.replace(`{field}`, fieldLabel).replace(`{min}`, ruleValue[0]);
|
|
102
99
|
} else if (
|
|
103
100
|
field.type === constants.types.NUMBER &&
|
|
104
101
|
typeChecks[constants.types.NUMBER](fieldValue) &&
|
|
105
102
|
fieldValue < ruleValue[0]
|
|
106
103
|
) {
|
|
107
|
-
message =
|
|
108
|
-
|
|
109
|
-
fieldLabel,
|
|
110
|
-
).replace(`{min}`, ruleValue[0]);
|
|
104
|
+
message = custom_message ?? error_messages.MIN_NUMBER;
|
|
105
|
+
message = message?.replace(`{field}`, fieldLabel).replace(`{min}`, ruleValue[0]);
|
|
111
106
|
}
|
|
112
107
|
}
|
|
113
108
|
|
|
@@ -117,19 +112,15 @@ const handleMinMaxValidation = (
|
|
|
117
112
|
typeChecks[constants.types.STRING](fieldValue) &&
|
|
118
113
|
fieldValue?.length > ruleValue[0]
|
|
119
114
|
) {
|
|
120
|
-
message =
|
|
121
|
-
|
|
122
|
-
fieldLabel,
|
|
123
|
-
).replace(`{max}`, ruleValue[0]);
|
|
115
|
+
message = custom_message ?? error_messages.MAX_STRING;
|
|
116
|
+
message = message?.replace(`{field}`, fieldLabel).replace(`{max}`, ruleValue[0]);
|
|
124
117
|
} else if (
|
|
125
118
|
field.type === constants.types.NUMBER &&
|
|
126
119
|
typeChecks[constants.types.NUMBER](fieldValue) &&
|
|
127
120
|
fieldValue > ruleValue[0]
|
|
128
121
|
) {
|
|
129
|
-
message =
|
|
130
|
-
|
|
131
|
-
fieldLabel,
|
|
132
|
-
).replace(`{max}`, ruleValue[0]);
|
|
122
|
+
message = custom_message ?? error_messages.MAX_NUMBER;
|
|
123
|
+
message = message?.replace(`{field}`, fieldLabel).replace(`{max}`, ruleValue[0]);
|
|
133
124
|
}
|
|
134
125
|
}
|
|
135
126
|
|
|
@@ -137,7 +128,7 @@ const handleMinMaxValidation = (
|
|
|
137
128
|
addError(
|
|
138
129
|
currentPath,
|
|
139
130
|
{ label: fieldLabel, fieldPath: currentPath, description: "", message },
|
|
140
|
-
field
|
|
131
|
+
field
|
|
141
132
|
);
|
|
142
133
|
}
|
|
143
134
|
};
|
|
@@ -148,15 +139,13 @@ const validateMetaRules = (
|
|
|
148
139
|
providedValue,
|
|
149
140
|
currentPath,
|
|
150
141
|
updateValue,
|
|
142
|
+
error_messages
|
|
151
143
|
) => {
|
|
152
144
|
const fieldValue = providedValue;
|
|
153
145
|
const { required = false, nullable = false } = field?.meta ?? {};
|
|
154
146
|
|
|
155
147
|
if (required && isEmpty(fieldValue) && fieldValue !== null) {
|
|
156
|
-
const message =
|
|
157
|
-
`{field}`,
|
|
158
|
-
formatLabel(field.display_label),
|
|
159
|
-
);
|
|
148
|
+
const message = error_messages.REQUIRED.replace(`{field}`, formatLabel(field.display_label));
|
|
160
149
|
addError(
|
|
161
150
|
currentPath,
|
|
162
151
|
{
|
|
@@ -165,14 +154,14 @@ const validateMetaRules = (
|
|
|
165
154
|
description: "",
|
|
166
155
|
message,
|
|
167
156
|
},
|
|
168
|
-
field
|
|
157
|
+
field
|
|
169
158
|
);
|
|
170
159
|
}
|
|
171
160
|
|
|
172
161
|
if (!nullable && fieldValue === null) {
|
|
173
|
-
const message =
|
|
162
|
+
const message = error_messages.NOT_NULLABLE.replace(
|
|
174
163
|
`{field}`,
|
|
175
|
-
formatLabel(field.display_label)
|
|
164
|
+
formatLabel(field.display_label)
|
|
176
165
|
);
|
|
177
166
|
addError(
|
|
178
167
|
currentPath,
|
|
@@ -182,7 +171,7 @@ const validateMetaRules = (
|
|
|
182
171
|
description: "",
|
|
183
172
|
message,
|
|
184
173
|
},
|
|
185
|
-
field
|
|
174
|
+
field
|
|
186
175
|
);
|
|
187
176
|
}
|
|
188
177
|
|
|
@@ -191,9 +180,9 @@ const validateMetaRules = (
|
|
|
191
180
|
typeChecks[field.type] &&
|
|
192
181
|
!typeChecks[field.type](fieldValue, { key: currentPath, updateValue })
|
|
193
182
|
) {
|
|
194
|
-
const message =
|
|
183
|
+
const message = error_messages.INVALID_TYPE.replace(
|
|
195
184
|
`{field}`,
|
|
196
|
-
formatLabel(field.display_label)
|
|
185
|
+
formatLabel(field.display_label)
|
|
197
186
|
).replace(`{type}`, field?.type);
|
|
198
187
|
addError(
|
|
199
188
|
currentPath,
|
|
@@ -203,7 +192,7 @@ const validateMetaRules = (
|
|
|
203
192
|
description: "",
|
|
204
193
|
message,
|
|
205
194
|
},
|
|
206
|
-
field
|
|
195
|
+
field
|
|
207
196
|
);
|
|
208
197
|
}
|
|
209
198
|
};
|
|
@@ -214,6 +203,8 @@ const handleRegexValidation = (
|
|
|
214
203
|
field,
|
|
215
204
|
addError,
|
|
216
205
|
currentPath,
|
|
206
|
+
error_messages,
|
|
207
|
+
custom_message
|
|
217
208
|
) => {
|
|
218
209
|
let message = "";
|
|
219
210
|
const fieldLabel = formatLabel(field.display_label);
|
|
@@ -225,38 +216,28 @@ const handleRegexValidation = (
|
|
|
225
216
|
const isValid = (() => {
|
|
226
217
|
switch (rule.options.type) {
|
|
227
218
|
case constants.regexTypes.MATCH:
|
|
228
|
-
message =
|
|
219
|
+
message = custom_message ?? error_messages.REGEX_MATCH;
|
|
229
220
|
return regex.test(fieldValue);
|
|
230
221
|
case constants.regexTypes.START_WITH:
|
|
231
|
-
message =
|
|
232
|
-
return fieldValue?.startsWith(
|
|
233
|
-
rule.value[0].replace(/^\//, "").replace(/\/$/, ""),
|
|
234
|
-
);
|
|
222
|
+
message = custom_message ?? error_messages.REGEX_START_WITH;
|
|
223
|
+
return fieldValue?.startsWith(rule.value[0].replace(/^\//, "").replace(/\/$/, ""));
|
|
235
224
|
case constants.regexTypes.ENDS_WITH:
|
|
236
|
-
message =
|
|
237
|
-
return fieldValue?.endsWith(
|
|
238
|
-
rule.value[0].replace(/^\//, "").replace(/\/$/, ""),
|
|
239
|
-
);
|
|
225
|
+
message = custom_message ?? error_messages.REGEX_ENDS_WITH;
|
|
226
|
+
return fieldValue?.endsWith(rule.value[0].replace(/^\//, "").replace(/\/$/, ""));
|
|
240
227
|
case constants.regexTypes.CONTAINS:
|
|
241
|
-
message =
|
|
228
|
+
message = custom_message ?? error_messages.REGEX_CONTAINS;
|
|
242
229
|
return regex.test(fieldValue);
|
|
243
230
|
case constants.regexTypes.EXACT:
|
|
244
|
-
message =
|
|
245
|
-
return (
|
|
246
|
-
fieldValue === rule.value[0].replace(/^\//, "").replace(/\/$/, "")
|
|
247
|
-
);
|
|
231
|
+
message = custom_message ?? error_messages.REGEX_EXACT;
|
|
232
|
+
return fieldValue === rule.value[0].replace(/^\//, "").replace(/\/$/, "");
|
|
248
233
|
case constants.regexTypes.NOT_START_WITH:
|
|
249
|
-
message =
|
|
250
|
-
return !fieldValue?.startsWith(
|
|
251
|
-
rule.value[0].replace(/^\//, "").replace(/\/$/, ""),
|
|
252
|
-
);
|
|
234
|
+
message = custom_message ?? error_messages.REGEX_NOT_START_WITH;
|
|
235
|
+
return !fieldValue?.startsWith(rule.value[0].replace(/^\//, "").replace(/\/$/, ""));
|
|
253
236
|
case constants.regexTypes.NOT_ENDS_WITH:
|
|
254
|
-
message =
|
|
255
|
-
return !fieldValue?.endsWith(
|
|
256
|
-
rule.value[0].replace(/^\//, "").replace(/\/$/, ""),
|
|
257
|
-
);
|
|
237
|
+
message = custom_message ?? error_messages.REGEX_NOT_ENDS_WITH;
|
|
238
|
+
return !fieldValue?.endsWith(rule.value[0].replace(/^\//, "").replace(/\/$/, ""));
|
|
258
239
|
case constants.regexTypes.NOT_CONTAINS:
|
|
259
|
-
message =
|
|
240
|
+
message = custom_message ?? error_messages.REGEX_NOT_CONTAINS;
|
|
260
241
|
return !regex.test(fieldValue);
|
|
261
242
|
default:
|
|
262
243
|
return false;
|
|
@@ -264,13 +245,11 @@ const handleRegexValidation = (
|
|
|
264
245
|
})();
|
|
265
246
|
|
|
266
247
|
if (!isValid) {
|
|
267
|
-
message = message
|
|
268
|
-
?.replace(`{field}`, fieldLabel)
|
|
269
|
-
?.replace(`{value}`, rule.value[0]);
|
|
248
|
+
message = message?.replace(`{field}`, fieldLabel)?.replace(`{value}`, rule.value[0]);
|
|
270
249
|
addError(
|
|
271
250
|
currentPath,
|
|
272
251
|
{ label: fieldLabel, fieldPath: currentPath, description: "", message },
|
|
273
|
-
field
|
|
252
|
+
field
|
|
274
253
|
);
|
|
275
254
|
}
|
|
276
255
|
};
|
|
@@ -282,6 +261,8 @@ const validateOperatorRule = (
|
|
|
282
261
|
addError,
|
|
283
262
|
currentPath,
|
|
284
263
|
formData,
|
|
264
|
+
error_messages,
|
|
265
|
+
custom_message
|
|
285
266
|
) => {
|
|
286
267
|
const { isFieldCompare = false } = rule?.options ?? {};
|
|
287
268
|
let valid = false;
|
|
@@ -304,7 +285,10 @@ const validateOperatorRule = (
|
|
|
304
285
|
const date = new Date(value);
|
|
305
286
|
date.setHours(0, 0, 0, 0);
|
|
306
287
|
if (forMessage) {
|
|
307
|
-
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(
|
|
288
|
+
return `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(
|
|
289
|
+
2,
|
|
290
|
+
"0"
|
|
291
|
+
)}-${String(date.getUTCDate()).padStart(2, "0")}`;
|
|
308
292
|
}
|
|
309
293
|
return Math.floor(date.getTime() / 1000);
|
|
310
294
|
}
|
|
@@ -313,8 +297,13 @@ const validateOperatorRule = (
|
|
|
313
297
|
|
|
314
298
|
if (forMessage) {
|
|
315
299
|
return (
|
|
316
|
-
`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(
|
|
317
|
-
|
|
300
|
+
`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, "0")}-${String(
|
|
301
|
+
date.getUTCDate()
|
|
302
|
+
).padStart(2, "0")} ` +
|
|
303
|
+
`${String(date.getUTCHours()).padStart(2, "0")}:${String(date.getUTCMinutes()).padStart(
|
|
304
|
+
2,
|
|
305
|
+
"0"
|
|
306
|
+
)}:${String(date.getUTCSeconds()).padStart(2, "0")}`
|
|
318
307
|
);
|
|
319
308
|
}
|
|
320
309
|
|
|
@@ -338,123 +327,116 @@ const validateOperatorRule = (
|
|
|
338
327
|
|
|
339
328
|
const fieldValueParsed = getComparableValue(fieldValue);
|
|
340
329
|
|
|
341
|
-
const messageValue = Array.isArray(rule.value)
|
|
342
|
-
? rule.value.join(", ")
|
|
343
|
-
: String(rule.value);
|
|
330
|
+
const messageValue = Array.isArray(rule.value) ? rule.value.join(", ") : String(rule.value);
|
|
344
331
|
let message = "";
|
|
345
332
|
|
|
346
333
|
switch (rule.options.operator) {
|
|
347
334
|
case constants.operatorTypes.AND:
|
|
348
|
-
message =
|
|
349
|
-
|
|
350
|
-
formatLabel(field.display_label)
|
|
351
|
-
|
|
335
|
+
message = custom_message ?? error_messages.AND;
|
|
336
|
+
message = message
|
|
337
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
338
|
+
?.replace("{value}", messageValue);
|
|
352
339
|
valid = isArray
|
|
353
340
|
? rule.value.every((val) => fieldValue.includes(val))
|
|
354
341
|
: rule.value.every((val) => val === fieldValueParsed);
|
|
355
342
|
break;
|
|
356
343
|
case constants.operatorTypes.OR:
|
|
357
|
-
message =
|
|
358
|
-
|
|
359
|
-
formatLabel(field.display_label)
|
|
360
|
-
|
|
344
|
+
message = custom_message ?? error_messages.OR;
|
|
345
|
+
message = message
|
|
346
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
347
|
+
?.replace("{value}", messageValue);
|
|
361
348
|
valid = isArray
|
|
362
349
|
? rule.value.some((val) => fieldValue.includes(val))
|
|
363
350
|
: rule.value.some((val) => val === fieldValueParsed);
|
|
364
351
|
break;
|
|
365
352
|
case constants.operatorTypes.EQUAL:
|
|
366
|
-
message =
|
|
367
|
-
|
|
368
|
-
formatLabel(field.display_label)
|
|
369
|
-
|
|
353
|
+
message = custom_message ?? error_messages.EQUAL;
|
|
354
|
+
message = message
|
|
355
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
356
|
+
?.replace("{value}", rule.value[0]);
|
|
370
357
|
valid = fieldValueParsed === getComparableValue(rule.value[0]);
|
|
371
358
|
break;
|
|
372
359
|
case constants.operatorTypes.NOT_EQUAL:
|
|
373
|
-
message =
|
|
374
|
-
|
|
375
|
-
formatLabel(field.display_label)
|
|
376
|
-
|
|
360
|
+
message = custom_message ?? error_messages.NOT_EQUAL;
|
|
361
|
+
message = message
|
|
362
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
363
|
+
?.replace("{value}", rule.value[0]);
|
|
377
364
|
valid = fieldValueParsed !== getComparableValue(rule.value[0]);
|
|
378
365
|
break;
|
|
379
366
|
case constants.operatorTypes.LESS_THAN:
|
|
380
|
-
message =
|
|
381
|
-
|
|
382
|
-
formatLabel(field.display_label)
|
|
383
|
-
|
|
367
|
+
message = custom_message ?? error_messages.LESS_THAN;
|
|
368
|
+
message = message
|
|
369
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
370
|
+
?.replace("{value}", rule.value[0]);
|
|
384
371
|
valid = fieldValueParsed < getComparableValue(rule.value[0]);
|
|
385
372
|
break;
|
|
386
373
|
case constants.operatorTypes.LESS_THAN_EQUAL:
|
|
387
|
-
message =
|
|
388
|
-
|
|
389
|
-
formatLabel(field.display_label)
|
|
390
|
-
|
|
374
|
+
message = custom_message ?? error_messages.LESS_THAN_EQUAL;
|
|
375
|
+
message = message
|
|
376
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
377
|
+
?.replace("{value}", rule.value[0]);
|
|
391
378
|
valid = fieldValueParsed <= getComparableValue(rule.value[0]);
|
|
392
379
|
break;
|
|
393
380
|
case constants.operatorTypes.GREATER_THAN:
|
|
394
|
-
message =
|
|
395
|
-
|
|
396
|
-
formatLabel(field.display_label)
|
|
397
|
-
|
|
381
|
+
message = custom_message ?? error_messages.GREATER_THAN;
|
|
382
|
+
message = message
|
|
383
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
384
|
+
?.replace("{value}", rule.value[0]);
|
|
398
385
|
valid = fieldValueParsed > getComparableValue(rule.value[0]);
|
|
399
386
|
break;
|
|
400
387
|
case constants.operatorTypes.GREATER_THAN_EQUAL:
|
|
401
|
-
message =
|
|
402
|
-
|
|
403
|
-
formatLabel(field.display_label)
|
|
404
|
-
|
|
388
|
+
message = custom_message ?? error_messages.GREATER_THAN_EQUAL;
|
|
389
|
+
message = message
|
|
390
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
391
|
+
?.replace("{value}", rule.value[0]);
|
|
405
392
|
valid = fieldValueParsed >= getComparableValue(rule.value[0]);
|
|
406
393
|
break;
|
|
407
394
|
case constants.operatorTypes.IN:
|
|
408
|
-
message =
|
|
409
|
-
|
|
410
|
-
formatLabel(field.display_label)
|
|
411
|
-
|
|
395
|
+
message = custom_message ?? error_messages.IN;
|
|
396
|
+
message = message
|
|
397
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
398
|
+
?.replace("{value}", messageValue);
|
|
412
399
|
valid = rule.value.includes(fieldValue);
|
|
413
400
|
break;
|
|
414
401
|
case constants.operatorTypes.NOT_IN:
|
|
415
|
-
message =
|
|
416
|
-
|
|
417
|
-
formatLabel(field.display_label)
|
|
418
|
-
|
|
402
|
+
message = custom_message ?? error_messages.NOT_IN;
|
|
403
|
+
message = message
|
|
404
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
405
|
+
?.replace("{value}", messageValue);
|
|
419
406
|
valid = !rule.value.includes(fieldValue);
|
|
420
407
|
break;
|
|
421
408
|
case constants.operatorTypes.EXISTS:
|
|
422
|
-
message =
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
);
|
|
426
|
-
valid = rule.value[0]
|
|
427
|
-
? fieldValue !== undefined
|
|
428
|
-
: fieldValue === undefined;
|
|
409
|
+
message = custom_message ?? error_messages.EXISTS;
|
|
410
|
+
message = message?.replace(`{field}`, formatLabel(field.display_label));
|
|
411
|
+
valid = rule.value[0] ? fieldValue !== undefined : fieldValue === undefined;
|
|
429
412
|
break;
|
|
430
413
|
case constants.operatorTypes.TYPE:
|
|
431
|
-
message =
|
|
432
|
-
|
|
433
|
-
formatLabel(field.display_label)
|
|
434
|
-
|
|
414
|
+
message = custom_message ?? error_messages.TYPE;
|
|
415
|
+
message = message
|
|
416
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
417
|
+
?.replace("{value}", rule.value[0]);
|
|
435
418
|
valid = typeChecks[rule.value[0]](fieldValue);
|
|
436
419
|
break;
|
|
437
420
|
case constants.operatorTypes.MOD:
|
|
438
|
-
message =
|
|
439
|
-
|
|
440
|
-
formatLabel(field.display_label)
|
|
441
|
-
)
|
|
421
|
+
message = custom_message ?? error_messages.MOD;
|
|
422
|
+
message = message
|
|
423
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
442
424
|
?.replace("{value[1]}", rule.value[1])
|
|
443
425
|
?.replace("{value[0]}", rule.value[0]);
|
|
444
426
|
valid = isNumber && fieldValue % rule.value[0] === rule.value[1];
|
|
445
427
|
break;
|
|
446
428
|
case constants.operatorTypes.ALL:
|
|
447
|
-
message =
|
|
448
|
-
|
|
449
|
-
formatLabel(field.display_label)
|
|
450
|
-
|
|
429
|
+
message = custom_message ?? error_messages.ALL;
|
|
430
|
+
message = message
|
|
431
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
432
|
+
?.replace("{value}", messageValue);
|
|
451
433
|
valid = isArray && rule.value.every((val) => fieldValue.includes(val));
|
|
452
434
|
break;
|
|
453
435
|
case constants.operatorTypes.SIZE:
|
|
454
|
-
message =
|
|
455
|
-
|
|
456
|
-
formatLabel(field.display_label)
|
|
457
|
-
|
|
436
|
+
message = custom_message ?? error_messages.SIZE;
|
|
437
|
+
message = message
|
|
438
|
+
?.replace(`{field}`, formatLabel(field.display_label))
|
|
439
|
+
?.replace("{value}", rule.value[0]);
|
|
458
440
|
valid = isArray && fieldValue.length === rule.value[0];
|
|
459
441
|
break;
|
|
460
442
|
default:
|
|
@@ -470,58 +452,67 @@ const validateOperatorRule = (
|
|
|
470
452
|
description: "",
|
|
471
453
|
message,
|
|
472
454
|
},
|
|
473
|
-
field
|
|
455
|
+
field
|
|
474
456
|
);
|
|
475
457
|
}
|
|
476
458
|
};
|
|
477
459
|
|
|
478
|
-
const generateErrorMessage = (
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
460
|
+
const generateErrorMessage = (
|
|
461
|
+
ruleKey,
|
|
462
|
+
fieldLabel,
|
|
463
|
+
additionalValues = {},
|
|
464
|
+
error_messages,
|
|
465
|
+
custom_message
|
|
466
|
+
) => {
|
|
467
|
+
let message = custom_message ?? error_messages[ruleKey];
|
|
468
|
+
message = message?.replace(`{field}`, fieldLabel);
|
|
483
469
|
Object.entries(additionalValues).forEach(([key, value]) => {
|
|
484
470
|
message = message.replace(`{${key}}`, value);
|
|
485
471
|
});
|
|
486
472
|
return message;
|
|
487
473
|
};
|
|
488
474
|
|
|
489
|
-
const handleRule = (rule, field, value, addError, currentPath, formData) => {
|
|
475
|
+
const handleRule = (rule, field, value, addError, currentPath, formData, error_messages) => {
|
|
490
476
|
const ruleValue = rule?.value;
|
|
491
|
-
const messageValue = Array.isArray(ruleValue)
|
|
492
|
-
? ruleValue.join(", ")
|
|
493
|
-
: String(ruleValue);
|
|
477
|
+
const messageValue = Array.isArray(ruleValue) ? ruleValue.join(", ") : String(ruleValue);
|
|
494
478
|
const fieldLabel = formatLabel(field.display_label);
|
|
479
|
+
const custom_message = rule?.custom_message;
|
|
495
480
|
|
|
496
|
-
const addValidationError = (ruleKey, extraValues = {}) =>
|
|
481
|
+
const addValidationError = (ruleKey, extraValues = {}, custom_message) =>
|
|
497
482
|
addError(
|
|
498
483
|
currentPath,
|
|
499
484
|
{
|
|
500
485
|
label: fieldLabel,
|
|
501
486
|
fieldPath: currentPath,
|
|
502
487
|
description: "",
|
|
503
|
-
message: generateErrorMessage(
|
|
488
|
+
message: generateErrorMessage(
|
|
489
|
+
ruleKey,
|
|
490
|
+
fieldLabel,
|
|
491
|
+
extraValues,
|
|
492
|
+
error_messages,
|
|
493
|
+
custom_message
|
|
494
|
+
),
|
|
504
495
|
},
|
|
505
|
-
field
|
|
496
|
+
field
|
|
506
497
|
);
|
|
507
498
|
|
|
508
499
|
switch (rule.case) {
|
|
509
500
|
case constants.rulesTypes.EMPTY:
|
|
510
|
-
if (value) addValidationError("EMPTY");
|
|
501
|
+
if (value) addValidationError("EMPTY", {}, custom_message);
|
|
511
502
|
break;
|
|
512
503
|
case constants.rulesTypes.NOT_EMPTY:
|
|
513
|
-
if (!value || value.length === 0) addValidationError("NOT_EMPTY");
|
|
504
|
+
if (!value || value.length === 0) addValidationError("NOT_EMPTY", {}, custom_message);
|
|
514
505
|
break;
|
|
515
506
|
case constants.rulesTypes.ONE_OF:
|
|
516
507
|
if (!ruleValue?.includes(value))
|
|
517
|
-
addValidationError("ONE_OF", { value: messageValue });
|
|
508
|
+
addValidationError("ONE_OF", { value: messageValue }, custom_message);
|
|
518
509
|
break;
|
|
519
510
|
case constants.rulesTypes.NOT_ONE_OF:
|
|
520
511
|
if (ruleValue?.includes(value))
|
|
521
|
-
addValidationError("NOT_ONE_OF", { value: messageValue });
|
|
512
|
+
addValidationError("NOT_ONE_OF", { value: messageValue }, custom_message);
|
|
522
513
|
break;
|
|
523
514
|
case constants.rulesTypes.NOT_ALLOWED:
|
|
524
|
-
if (ruleValue?.includes(value)) addValidationError("NOT_ALLOWED");
|
|
515
|
+
if (ruleValue?.includes(value)) addValidationError("NOT_ALLOWED", {}, custom_message);
|
|
525
516
|
break;
|
|
526
517
|
case constants.rulesTypes.MIN:
|
|
527
518
|
case constants.rulesTypes.MAX:
|
|
@@ -532,13 +523,32 @@ const handleRule = (rule, field, value, addError, currentPath, formData) => {
|
|
|
532
523
|
field,
|
|
533
524
|
addError,
|
|
534
525
|
currentPath,
|
|
526
|
+
error_messages,
|
|
527
|
+
custom_message
|
|
535
528
|
);
|
|
536
529
|
break;
|
|
537
530
|
case constants.rulesTypes.REGEX:
|
|
538
|
-
handleRegexValidation(
|
|
531
|
+
handleRegexValidation(
|
|
532
|
+
value,
|
|
533
|
+
rule,
|
|
534
|
+
field,
|
|
535
|
+
addError,
|
|
536
|
+
currentPath,
|
|
537
|
+
error_messages,
|
|
538
|
+
custom_message
|
|
539
|
+
);
|
|
539
540
|
break;
|
|
540
541
|
case constants.rulesTypes.OPERATOR:
|
|
541
|
-
validateOperatorRule(
|
|
542
|
+
validateOperatorRule(
|
|
543
|
+
value,
|
|
544
|
+
rule,
|
|
545
|
+
field,
|
|
546
|
+
addError,
|
|
547
|
+
currentPath,
|
|
548
|
+
formData,
|
|
549
|
+
error_messages,
|
|
550
|
+
custom_message
|
|
551
|
+
);
|
|
542
552
|
break;
|
|
543
553
|
default:
|
|
544
554
|
console.warn(`Unknown Rule: ${rule.case}`, fieldLabel);
|
|
@@ -552,13 +562,12 @@ const validateField = (
|
|
|
552
562
|
addError,
|
|
553
563
|
formData,
|
|
554
564
|
updateValue,
|
|
565
|
+
error_messages
|
|
555
566
|
) => {
|
|
556
|
-
const currentPath = fieldPath
|
|
557
|
-
? `${fieldPath}.${field.key.split(".").pop()}`
|
|
558
|
-
: field.key;
|
|
567
|
+
const currentPath = fieldPath ? `${fieldPath}.${field.key.split(".").pop()}` : field.key;
|
|
559
568
|
const fieldLabel = formatLabel(field.display_label);
|
|
560
569
|
|
|
561
|
-
validateMetaRules(field, addError, value, currentPath, updateValue);
|
|
570
|
+
validateMetaRules(field, addError, value, currentPath, updateValue, error_messages);
|
|
562
571
|
|
|
563
572
|
if (
|
|
564
573
|
field.type === constants.types.OBJECT &&
|
|
@@ -572,8 +581,10 @@ const validateField = (
|
|
|
572
581
|
value[child.key.split(".").pop()],
|
|
573
582
|
currentPath,
|
|
574
583
|
addError,
|
|
584
|
+
formData,
|
|
575
585
|
updateValue,
|
|
576
|
-
|
|
586
|
+
error_messages
|
|
587
|
+
)
|
|
577
588
|
);
|
|
578
589
|
} else if (field.type === constants.types.ARRAY && Array.isArray(value)) {
|
|
579
590
|
const itemType = field?.array_type || field?.schema_definition?.type;
|
|
@@ -584,9 +595,14 @@ const validateField = (
|
|
|
584
595
|
label: fieldLabel,
|
|
585
596
|
fieldPath: `${currentPath}[${index}]`,
|
|
586
597
|
description: "",
|
|
587
|
-
message: generateErrorMessage(
|
|
588
|
-
|
|
589
|
-
|
|
598
|
+
message: generateErrorMessage(
|
|
599
|
+
"INVALID_TYPE",
|
|
600
|
+
fieldLabel,
|
|
601
|
+
{
|
|
602
|
+
type: itemType,
|
|
603
|
+
},
|
|
604
|
+
error_messages
|
|
605
|
+
),
|
|
590
606
|
});
|
|
591
607
|
}
|
|
592
608
|
});
|
|
@@ -599,32 +615,34 @@ const validateField = (
|
|
|
599
615
|
item[child.key.split(".").pop()],
|
|
600
616
|
`${currentPath}[${index}]`,
|
|
601
617
|
addError,
|
|
618
|
+
formData,
|
|
602
619
|
updateValue,
|
|
603
|
-
|
|
620
|
+
error_messages
|
|
621
|
+
)
|
|
604
622
|
);
|
|
605
623
|
});
|
|
606
624
|
}
|
|
607
625
|
} else {
|
|
608
|
-
if (!applyValidations(field, value, addError, currentPath, formData)) {
|
|
626
|
+
if (!applyValidations(field, value, addError, currentPath, formData, error_messages)) {
|
|
609
627
|
addError(
|
|
610
628
|
currentPath,
|
|
611
629
|
{
|
|
612
630
|
label: fieldLabel,
|
|
613
631
|
fieldPath: currentPath,
|
|
614
632
|
description: "",
|
|
615
|
-
message: `
|
|
633
|
+
message: error_messages.INVALID_VALUE?.replace(`{field}`, fieldLabel),
|
|
616
634
|
},
|
|
617
|
-
field
|
|
635
|
+
field
|
|
618
636
|
);
|
|
619
637
|
}
|
|
620
638
|
}
|
|
621
639
|
};
|
|
622
640
|
|
|
623
|
-
const applyValidations = (field, value, addError, currentPath, formData) => {
|
|
641
|
+
const applyValidations = (field, value, addError, currentPath, formData, error_messages) => {
|
|
624
642
|
if (!field.validations || value === null || value === undefined) return true;
|
|
625
643
|
return !field.validations.some(
|
|
626
644
|
(rule) =>
|
|
627
|
-
handleRule(rule, field, value, addError, currentPath, formData) === false
|
|
645
|
+
handleRule(rule, field, value, addError, currentPath, formData, error_messages) === false
|
|
628
646
|
);
|
|
629
647
|
};
|
|
630
648
|
|
|
@@ -644,6 +662,7 @@ const schema = {
|
|
|
644
662
|
array_type: constants.types.STRING,
|
|
645
663
|
},
|
|
646
664
|
apiVersion: { type: constants.types.STRING, array_type: null },
|
|
665
|
+
language: { type: constants.types.STRING, array_type: null },
|
|
647
666
|
};
|
|
648
667
|
|
|
649
668
|
const validate = (data) => {
|
|
@@ -657,7 +676,13 @@ const validate = (data) => {
|
|
|
657
676
|
abortEarly,
|
|
658
677
|
byPassKeys,
|
|
659
678
|
apiVersion,
|
|
679
|
+
language,
|
|
660
680
|
} = data;
|
|
681
|
+
const defaultLanguage = constants.LANGUAGES.length > 0 ? constants.LANGUAGES[0] : "en"; // Replace "en" with your actual default
|
|
682
|
+
const error_messages =
|
|
683
|
+
constants.LOCALE_MESSAGES[language] ?? constants.LOCALE_MESSAGES[defaultLanguage];
|
|
684
|
+
|
|
685
|
+
|
|
661
686
|
let result = { status: true, errors: {}, data: formData };
|
|
662
687
|
|
|
663
688
|
const updateValue = (key, value) => {
|
|
@@ -678,10 +703,7 @@ const validate = (data) => {
|
|
|
678
703
|
// Validate Data
|
|
679
704
|
const defaultField = { meta: { hidden: false } };
|
|
680
705
|
if (!data) {
|
|
681
|
-
const message =
|
|
682
|
-
`{field}`,
|
|
683
|
-
formatLabel("data"),
|
|
684
|
-
);
|
|
706
|
+
const message = error_messages.REQUIRED.replace(`{field}`, formatLabel("data"));
|
|
685
707
|
addError(
|
|
686
708
|
"data",
|
|
687
709
|
{
|
|
@@ -690,17 +712,17 @@ const validate = (data) => {
|
|
|
690
712
|
description: "",
|
|
691
713
|
message,
|
|
692
714
|
},
|
|
693
|
-
defaultField
|
|
715
|
+
defaultField
|
|
694
716
|
);
|
|
695
717
|
return result;
|
|
696
718
|
}
|
|
697
719
|
|
|
698
720
|
// validate data type
|
|
699
721
|
if (!typeChecks[constants.types.OBJECT](data)) {
|
|
700
|
-
const message =
|
|
701
|
-
`{
|
|
702
|
-
|
|
703
|
-
)
|
|
722
|
+
const message = error_messages.INVALID_TYPE.replace(`{field}`, formatLabel("data")).replace(
|
|
723
|
+
`{type}`,
|
|
724
|
+
constants.types.OBJECT
|
|
725
|
+
);
|
|
704
726
|
addError(
|
|
705
727
|
"data",
|
|
706
728
|
{
|
|
@@ -709,7 +731,7 @@ const validate = (data) => {
|
|
|
709
731
|
description: "",
|
|
710
732
|
message,
|
|
711
733
|
},
|
|
712
|
-
defaultField
|
|
734
|
+
defaultField
|
|
713
735
|
);
|
|
714
736
|
return result;
|
|
715
737
|
}
|
|
@@ -720,10 +742,7 @@ const validate = (data) => {
|
|
|
720
742
|
const fieldValue = data[key];
|
|
721
743
|
// Skip empty values
|
|
722
744
|
if (fieldValue == null || fieldValue == undefined) {
|
|
723
|
-
const message =
|
|
724
|
-
`{field}`,
|
|
725
|
-
formatLabel(key),
|
|
726
|
-
);
|
|
745
|
+
const message = error_messages.REQUIRED.replace(`{field}`, formatLabel(key));
|
|
727
746
|
addError(
|
|
728
747
|
key,
|
|
729
748
|
{
|
|
@@ -732,17 +751,17 @@ const validate = (data) => {
|
|
|
732
751
|
description: "",
|
|
733
752
|
message,
|
|
734
753
|
},
|
|
735
|
-
defaultField
|
|
754
|
+
defaultField
|
|
736
755
|
);
|
|
737
756
|
return;
|
|
738
757
|
}
|
|
739
758
|
|
|
740
759
|
// Validate field type
|
|
741
760
|
if (!typeChecks[expectedType] || !typeChecks[expectedType](fieldValue)) {
|
|
742
|
-
const message =
|
|
743
|
-
`{
|
|
744
|
-
|
|
745
|
-
)
|
|
761
|
+
const message = error_messages.INVALID_TYPE.replace(`{field}`, key).replace(
|
|
762
|
+
`{type}`,
|
|
763
|
+
expectedType
|
|
764
|
+
);
|
|
746
765
|
addError(
|
|
747
766
|
key,
|
|
748
767
|
{
|
|
@@ -751,7 +770,7 @@ const validate = (data) => {
|
|
|
751
770
|
description: "",
|
|
752
771
|
message,
|
|
753
772
|
},
|
|
754
|
-
defaultField
|
|
773
|
+
defaultField
|
|
755
774
|
);
|
|
756
775
|
return;
|
|
757
776
|
}
|
|
@@ -762,14 +781,10 @@ const validate = (data) => {
|
|
|
762
781
|
// Determine the expected type of array items
|
|
763
782
|
const arrayItemType = schema[key].array_type; // Define item types like "relations[]": "object"
|
|
764
783
|
|
|
765
|
-
if (
|
|
766
|
-
|
|
767
|
-
typeChecks[arrayItemType] &&
|
|
768
|
-
!typeChecks[arrayItemType](item)
|
|
769
|
-
) {
|
|
770
|
-
const message = constants.rulesMessages.INVALID_TYPE.replace(
|
|
784
|
+
if (arrayItemType && typeChecks[arrayItemType] && !typeChecks[arrayItemType](item)) {
|
|
785
|
+
const message = error_messages.INVALID_TYPE.replace(
|
|
771
786
|
`{field}`,
|
|
772
|
-
`${key}[${index}]
|
|
787
|
+
`${key}[${index}]`
|
|
773
788
|
).replace(`{type}`, arrayItemType);
|
|
774
789
|
addError(
|
|
775
790
|
`${key}[${index}]`,
|
|
@@ -779,7 +794,7 @@ const validate = (data) => {
|
|
|
779
794
|
description: "",
|
|
780
795
|
message,
|
|
781
796
|
},
|
|
782
|
-
defaultField
|
|
797
|
+
defaultField
|
|
783
798
|
);
|
|
784
799
|
}
|
|
785
800
|
});
|
|
@@ -788,10 +803,10 @@ const validate = (data) => {
|
|
|
788
803
|
|
|
789
804
|
// Validate API Version
|
|
790
805
|
if (!constants.API_VERSIONS.includes(apiVersion)) {
|
|
791
|
-
const message =
|
|
792
|
-
`{
|
|
793
|
-
|
|
794
|
-
)
|
|
806
|
+
const message = error_messages.IN.replace(`{field}`, formatLabel("apiVersion")).replace(
|
|
807
|
+
`{value}`,
|
|
808
|
+
constants.API_VERSIONS.join(", ")
|
|
809
|
+
);
|
|
795
810
|
addError(
|
|
796
811
|
"apiVersion",
|
|
797
812
|
{
|
|
@@ -800,7 +815,7 @@ const validate = (data) => {
|
|
|
800
815
|
description: "",
|
|
801
816
|
message,
|
|
802
817
|
},
|
|
803
|
-
defaultField
|
|
818
|
+
defaultField
|
|
804
819
|
);
|
|
805
820
|
}
|
|
806
821
|
|
|
@@ -815,9 +830,7 @@ const validate = (data) => {
|
|
|
815
830
|
let allFields = isSeparatedFields ? [] : fields;
|
|
816
831
|
|
|
817
832
|
if (!isSeparatedFields) {
|
|
818
|
-
schemaFields = fields.filter(
|
|
819
|
-
(field) => field?.schema_id?.toString() === formId?.toString(),
|
|
820
|
-
);
|
|
833
|
+
schemaFields = fields.filter((field) => field?.schema_id?.toString() === formId?.toString());
|
|
821
834
|
}
|
|
822
835
|
|
|
823
836
|
const fieldOptions =
|
|
@@ -828,7 +841,7 @@ const validate = (data) => {
|
|
|
828
841
|
formData,
|
|
829
842
|
relationalFields,
|
|
830
843
|
isSeparatedFields,
|
|
831
|
-
apiVersion
|
|
844
|
+
apiVersion
|
|
832
845
|
) || [];
|
|
833
846
|
|
|
834
847
|
findDisallowedKeys(formData, fieldOptions).forEach((fieldPath) => {
|
|
@@ -845,6 +858,7 @@ const validate = (data) => {
|
|
|
845
858
|
{
|
|
846
859
|
field: formatLabel(fieldKey),
|
|
847
860
|
},
|
|
861
|
+
error_messages
|
|
848
862
|
),
|
|
849
863
|
});
|
|
850
864
|
}
|
|
@@ -859,9 +873,10 @@ const validate = (data) => {
|
|
|
859
873
|
addError,
|
|
860
874
|
formData,
|
|
861
875
|
updateValue,
|
|
876
|
+
error_messages
|
|
862
877
|
);
|
|
863
878
|
});
|
|
864
879
|
return result;
|
|
865
880
|
};
|
|
866
881
|
|
|
867
|
-
module.exports = { validate, validateField
|
|
882
|
+
module.exports = { validate, validateField, typeChecks };
|