pols-validator 1.0.1 → 1.1.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.
- package/dist/index.d.ts +2 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -69
- package/dist/rules.d.ts +4 -1
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +127 -131
- package/dist/rulesEngine.d.ts +3 -6
- package/dist/rulesEngine.d.ts.map +1 -1
- package/dist/rulesEngine.js +3 -4
- package/dist/validate.d.ts +12 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +56 -0
- package/package.json +1 -1
- package/src/index.ts +3 -82
- package/src/rules.ts +120 -134
- package/src/rulesEngine.ts +4 -7
- package/src/validate.ts +66 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { Rules } from "./rules";
|
|
2
|
-
import {
|
|
2
|
+
import { RulesParams } from "./rulesEngine";
|
|
3
3
|
export { RulesEngine } from './rulesEngine';
|
|
4
|
-
export
|
|
5
|
-
error: false;
|
|
6
|
-
success: true;
|
|
7
|
-
result: T;
|
|
8
|
-
} | {
|
|
9
|
-
error: true;
|
|
10
|
-
success: false;
|
|
11
|
-
messages: string[];
|
|
12
|
-
};
|
|
13
|
-
export declare const validate: <T>(target: unknown, rules: RulesEngine) => EvaluateResponse<T>;
|
|
4
|
+
export { EvaluateResponse, validate } from './validate';
|
|
14
5
|
export declare const rules: (params?: RulesParams) => Rules;
|
|
15
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEvD,eAAO,MAAM,KAAK,YAAa,WAAW,UAAsB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,77 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.rules = exports.validate = exports.RulesEngine = void 0;
|
|
4
|
-
const pols_utils_1 = require("pols-utils");
|
|
5
4
|
const rules_1 = require("./rules");
|
|
6
5
|
var rulesEngine_1 = require("./rulesEngine");
|
|
7
6
|
Object.defineProperty(exports, "RulesEngine", { enumerable: true, get: function () { return rulesEngine_1.RulesEngine; } });
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (typeof target == 'string')
|
|
11
|
-
target = target.trim();
|
|
12
|
-
const isEmpty = target == null || (typeof target == 'string' && !target);
|
|
13
|
-
const label = rules.label ?? 'Este valor';
|
|
14
|
-
if (rules.required && isEmpty) {
|
|
15
|
-
return {
|
|
16
|
-
error: true,
|
|
17
|
-
success: false,
|
|
18
|
-
messages: [`'${label}' es requerido`]
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
if (isEmpty) {
|
|
22
|
-
return {
|
|
23
|
-
error: false,
|
|
24
|
-
success: true,
|
|
25
|
-
result: rules.default
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const wrapper = {
|
|
29
|
-
value: pols_utils_1.PUtils.clone(target),
|
|
30
|
-
label
|
|
31
|
-
};
|
|
32
|
-
for (const validationFunction of Object.values(rules.collection)) {
|
|
33
|
-
const result = validationFunction(wrapper);
|
|
34
|
-
if (!result)
|
|
35
|
-
continue;
|
|
36
|
-
if (typeof result == 'string') {
|
|
37
|
-
errorMessages.push(result);
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
if (wrapper.value == null || typeof wrapper.value != 'object')
|
|
42
|
-
throw new Error(`El valor no es un objeto para ser validado contra un esquema: ${wrapper.value}`);
|
|
43
|
-
const newResult = {};
|
|
44
|
-
for (const key in result.schema) {
|
|
45
|
-
const rulesInside = result.schema[key];
|
|
46
|
-
const labelIndise = rulesInside.label ?? key;
|
|
47
|
-
rulesInside.label = `${result.prefix ? `${result.prefix} ` : ''}${labelIndise}`;
|
|
48
|
-
newResult[key] = wrapper.value[key];
|
|
49
|
-
const result2 = (0, exports.validate)(newResult[key], rulesInside);
|
|
50
|
-
if (result2.error == true) {
|
|
51
|
-
errorMessages.push(...result2.messages);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
newResult[key] = result2.result;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
wrapper.value = newResult;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (errorMessages.length) {
|
|
61
|
-
return {
|
|
62
|
-
error: true,
|
|
63
|
-
success: false,
|
|
64
|
-
messages: errorMessages
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
return {
|
|
69
|
-
error: false,
|
|
70
|
-
success: true,
|
|
71
|
-
result: wrapper.value
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
exports.validate = validate;
|
|
7
|
+
var validate_1 = require("./validate");
|
|
8
|
+
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return validate_1.validate; } });
|
|
76
9
|
const rules = (params) => new rules_1.Rules(params);
|
|
77
10
|
exports.rules = rules;
|
package/dist/rules.d.ts
CHANGED
|
@@ -13,10 +13,13 @@ export declare class Rules extends RulesEngine {
|
|
|
13
13
|
onlyNumbers(): this;
|
|
14
14
|
maxLength(limit: number): this;
|
|
15
15
|
minLength(limit: number): this;
|
|
16
|
-
|
|
16
|
+
hasFixedLength(limit: number): this;
|
|
17
17
|
left(limit: number): this;
|
|
18
|
+
isArray(): this;
|
|
19
|
+
isArrayOfObjects(schema?: (index: number) => Record<string, RulesEngine>, prefix?: (index: number) => string): this;
|
|
18
20
|
isIn(...elements: unknown[]): this;
|
|
19
21
|
isNotIn(...elements: unknown[]): this;
|
|
22
|
+
hasElements(): this;
|
|
20
23
|
gt(limit: number): this;
|
|
21
24
|
gte(limit: number): this;
|
|
22
25
|
lt(limit: number): this;
|
package/dist/rules.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAW,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAW,MAAM,eAAe,CAAA;AA2CpD,qBAAa,KAAM,SAAQ,WAAW;IACrC,cAAc;IAWd,cAAc;IAQd,UAAU;IAcV,MAAM;IAMN,MAAM;IA4BN,KAAK,CAAC,OAAO,EAAE,MAAM;IAQrB,QAAQ;IAUR,SAAS;IAQT,SAAS;IAIT,eAAe;IAIf,WAAW;IAQX,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,SAAS,CAAC,KAAK,EAAE,MAAM;IAYvB,cAAc,CAAC,KAAK,EAAE,MAAM;IAY5B,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,OAAO;IAiBP,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IAoB5G,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAa3B,OAAO,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAO9B,WAAW;IAMX,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,EAAE,CAAC,KAAK,EAAE,MAAM;IAMhB,GAAG,CAAC,KAAK,EAAE,MAAM;IAMjB,iBAAiB;IAOjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM;IAM9D,SAAS;IA+CT,KAAK;IAQL,KAAK;IAQL,SAAS;IAQT,KAAK,CAAC,QAAQ,EAAE,MAAM;IAStB,iBAAiB;IAQjB,QAAQ;IASR,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC;IAMlG,UAAU;IAQV,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAKhC"}
|
package/dist/rules.js
CHANGED
|
@@ -3,6 +3,47 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Rules = void 0;
|
|
4
4
|
const pols_utils_1 = require("pols-utils");
|
|
5
5
|
const rulesEngine_1 = require("./rulesEngine");
|
|
6
|
+
const validate_1 = require("./validate");
|
|
7
|
+
const isObject = (wrapper, schema, prefix) => {
|
|
8
|
+
const message = `'${wrapper.label}' debe ser un objeto`;
|
|
9
|
+
if (typeof wrapper.value == 'string') {
|
|
10
|
+
try {
|
|
11
|
+
wrapper.value = JSON.parse(wrapper.value);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return message;
|
|
15
|
+
}
|
|
16
|
+
if (pols_utils_1.PUtils.getType(wrapper.value) != 'Object')
|
|
17
|
+
return message;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
if (pols_utils_1.PUtils.getType(wrapper.value) != 'Object') {
|
|
21
|
+
return message;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/* Realiza la validación de cada propiedad */
|
|
25
|
+
const newWrapperValue = {};
|
|
26
|
+
const errorMessages = [];
|
|
27
|
+
for (const key in schema) {
|
|
28
|
+
const rulesInside = schema[key];
|
|
29
|
+
const labelIndise = rulesInside.label ?? key;
|
|
30
|
+
rulesInside.label = `${prefix ?? ''}${labelIndise}`;
|
|
31
|
+
newWrapperValue[key] = wrapper.value[key];
|
|
32
|
+
const result2 = (0, validate_1.validate)(newWrapperValue[key], rulesInside);
|
|
33
|
+
if (result2.error == true) {
|
|
34
|
+
errorMessages.push(...result2.messages);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
newWrapperValue[key] = result2.result;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (errorMessages.length) {
|
|
41
|
+
return errorMessages;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
wrapper.value = newWrapperValue;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
6
47
|
class Rules extends rulesEngine_1.RulesEngine {
|
|
7
48
|
isAlphanumeric() {
|
|
8
49
|
this.add(this.isAlphanumeric.name, (wrapper) => {
|
|
@@ -114,107 +155,90 @@ class Rules extends rulesEngine_1.RulesEngine {
|
|
|
114
155
|
return this;
|
|
115
156
|
}
|
|
116
157
|
maxLength(limit) {
|
|
117
|
-
this.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
158
|
+
return this.add(this.maxLength.name, (wrapper) => {
|
|
159
|
+
if (wrapper.value instanceof Array) {
|
|
160
|
+
return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como máximo` : null;
|
|
161
|
+
}
|
|
162
|
+
else if (typeof wrapper.value == 'string') {
|
|
163
|
+
return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como máximo` : null;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return `'${wrapper.label}' no es de un tipo válido`;
|
|
167
|
+
}
|
|
121
168
|
});
|
|
122
|
-
return this;
|
|
123
169
|
}
|
|
124
|
-
// maxCount(limit: number) {
|
|
125
|
-
// this.isArray()
|
|
126
|
-
// this.add(this.maxLength.name, (wrapper: Wrapper<unknown[]>) => {
|
|
127
|
-
// if (wrapper.value.length > limit) return `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elemento' : 'elementos'}' como máximo`
|
|
128
|
-
// })
|
|
129
|
-
// return this
|
|
130
|
-
// }
|
|
131
170
|
minLength(limit) {
|
|
132
|
-
this.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
171
|
+
return this.add(this.minLength.name, (wrapper) => {
|
|
172
|
+
if (wrapper.value instanceof Array) {
|
|
173
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como mínimo` : null;
|
|
174
|
+
}
|
|
175
|
+
else if (typeof wrapper.value == 'string') {
|
|
176
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como mínimo` : null;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return `'${wrapper.label}' no es de un tipo válido`;
|
|
180
|
+
}
|
|
136
181
|
});
|
|
137
|
-
return this;
|
|
138
182
|
}
|
|
139
|
-
|
|
140
|
-
this.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
183
|
+
hasFixedLength(limit) {
|
|
184
|
+
return this.add(this.hasFixedLength.name, (wrapper) => {
|
|
185
|
+
if (wrapper.value instanceof Array) {
|
|
186
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'elementos' : 'elementos'}'` : null;
|
|
187
|
+
}
|
|
188
|
+
else if (typeof wrapper.value == 'string') {
|
|
189
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}'` : null;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
return `'${wrapper.label}' no es de un tipo válido`;
|
|
193
|
+
}
|
|
144
194
|
});
|
|
145
|
-
return this;
|
|
146
195
|
}
|
|
147
196
|
left(limit) {
|
|
148
|
-
this.isAlphanumeric()
|
|
149
|
-
this.add(this.length.name, (wrapper) => {
|
|
197
|
+
return this.isAlphanumeric().add(this.left.name, (wrapper) => {
|
|
150
198
|
wrapper.value = wrapper.value.substring(0, limit);
|
|
151
199
|
});
|
|
152
|
-
return this;
|
|
153
200
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// }
|
|
196
|
-
// isArrayOfObjects(checkingElements?: (i: number) => FieldsStructure, prefixString?: (i: number) => string) {
|
|
197
|
-
// this.isArray()
|
|
198
|
-
// this.add(this.isArrayOfObjects.name, (wrapper: Wrapper<unknown[]>) => {
|
|
199
|
-
// const message = `'${wrapper.label}' debe ser una lista de objetos`
|
|
200
|
-
// const messages: string[] = []
|
|
201
|
-
// for (const [i, v] of wrapper.value.entries()) {
|
|
202
|
-
// const result = isObject(v)
|
|
203
|
-
// if (result.error == true) return message
|
|
204
|
-
// wrapper.value[i] = result.result
|
|
205
|
-
// if (checkingElements) {
|
|
206
|
-
// const v = wrapper.validator(wrapper.value[i], checkingElements(i), prefixString?.(i))
|
|
207
|
-
// if (v.error == true) {
|
|
208
|
-
// messages.push(...v.messages)
|
|
209
|
-
// } else {
|
|
210
|
-
// wrapper.value[i] = v.result
|
|
211
|
-
// }
|
|
212
|
-
// }
|
|
213
|
-
// }
|
|
214
|
-
// if (messages.length) return messages
|
|
215
|
-
// })
|
|
216
|
-
// return this
|
|
217
|
-
// }
|
|
201
|
+
isArray() {
|
|
202
|
+
return this.add(this.isArray.name, (wrapper) => {
|
|
203
|
+
const message = `'${wrapper.label}' debe ser una lista de elementos`;
|
|
204
|
+
if (typeof wrapper.value == 'string') {
|
|
205
|
+
try {
|
|
206
|
+
const value = JSON.parse(wrapper.value);
|
|
207
|
+
if (!(value instanceof Array))
|
|
208
|
+
return message;
|
|
209
|
+
wrapper.value = value;
|
|
210
|
+
}
|
|
211
|
+
catch (err) {
|
|
212
|
+
return message;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
if (!(wrapper.value instanceof Array))
|
|
217
|
+
return message;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
isArrayOfObjects(schema, prefix) {
|
|
222
|
+
return this.isArray().add(this.isArrayOfObjects.name, (wrapper) => {
|
|
223
|
+
const messages = [];
|
|
224
|
+
for (const [i, value] of wrapper.value.entries()) {
|
|
225
|
+
const v = isObject({
|
|
226
|
+
label: prefix?.(i) ?? `Item ${i}`,
|
|
227
|
+
value
|
|
228
|
+
}, schema?.(i));
|
|
229
|
+
if (v) {
|
|
230
|
+
if (v instanceof Array) {
|
|
231
|
+
messages.push(...v);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
messages.push(v);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (messages.length)
|
|
239
|
+
return messages;
|
|
240
|
+
});
|
|
241
|
+
}
|
|
218
242
|
isIn(...elements) {
|
|
219
243
|
this.add(this.isIn.name, (wrapper) => {
|
|
220
244
|
if (wrapper.value instanceof Array) {
|
|
@@ -237,49 +261,38 @@ class Rules extends rulesEngine_1.RulesEngine {
|
|
|
237
261
|
});
|
|
238
262
|
return this;
|
|
239
263
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// }
|
|
264
|
+
hasElements() {
|
|
265
|
+
return this.isArray().add(this.hasElements.name, (wrapper) => {
|
|
266
|
+
if (!wrapper.value.length)
|
|
267
|
+
return `'${wrapper.label}' debe contenedor al menos un elemento`;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
247
270
|
gt(limit) {
|
|
248
|
-
this.isNumber()
|
|
249
|
-
this.add(this.gt.name, (wrapper) => {
|
|
271
|
+
return this.isNumber().add(this.gt.name, (wrapper) => {
|
|
250
272
|
if (wrapper.value <= limit)
|
|
251
273
|
return `'${wrapper.label}' debe ser mayor a '${limit}'`;
|
|
252
274
|
});
|
|
253
|
-
return this;
|
|
254
275
|
}
|
|
255
276
|
gte(limit) {
|
|
256
|
-
this.isNumber()
|
|
257
|
-
this.add(this.gte.name, (wrapper) => {
|
|
277
|
+
return this.isNumber().add(this.gte.name, (wrapper) => {
|
|
258
278
|
if (wrapper.value < limit)
|
|
259
279
|
return `'${wrapper.label}' debe ser mayor o igual a '${limit}'`;
|
|
260
280
|
});
|
|
261
|
-
return this;
|
|
262
281
|
}
|
|
263
282
|
lt(limit) {
|
|
264
|
-
this.isNumber()
|
|
265
|
-
this.add(this.lt.name, (wrapper) => {
|
|
283
|
+
return this.isNumber().add(this.lt.name, (wrapper) => {
|
|
266
284
|
if (wrapper.value >= limit)
|
|
267
285
|
return `'${wrapper.label}' debe ser menor a '${limit}'`;
|
|
268
286
|
});
|
|
269
|
-
return this;
|
|
270
287
|
}
|
|
271
288
|
lte(limit) {
|
|
272
|
-
return this
|
|
273
|
-
.isNumber()
|
|
274
|
-
.add(this.lte.name, (wrapper) => {
|
|
289
|
+
return this.isNumber().add(this.lte.name, (wrapper) => {
|
|
275
290
|
if (wrapper.value > limit)
|
|
276
291
|
return `'${wrapper.label}' debe ser menor o igual a '${limit}'`;
|
|
277
292
|
});
|
|
278
293
|
}
|
|
279
294
|
beforeOrSameAsNow() {
|
|
280
|
-
return this
|
|
281
|
-
.isDateTime()
|
|
282
|
-
.add(this.beforeOrSameAsNow.name, (wrapper) => {
|
|
295
|
+
return this.isDateTime().add(this.beforeOrSameAsNow.name, (wrapper) => {
|
|
283
296
|
const now = new pols_utils_1.PDate;
|
|
284
297
|
if (wrapper.value.time > now.time)
|
|
285
298
|
return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`;
|
|
@@ -287,27 +300,11 @@ class Rules extends rulesEngine_1.RulesEngine {
|
|
|
287
300
|
}
|
|
288
301
|
isObject(schema, prefix) {
|
|
289
302
|
return this.add(this.isObject.name, (wrapper) => {
|
|
290
|
-
|
|
291
|
-
if (typeof wrapper.value == 'string') {
|
|
292
|
-
try {
|
|
293
|
-
wrapper.value = JSON.parse(wrapper.value);
|
|
294
|
-
}
|
|
295
|
-
catch {
|
|
296
|
-
return message;
|
|
297
|
-
}
|
|
298
|
-
if (pols_utils_1.PUtils.getType(wrapper.value) != 'Object')
|
|
299
|
-
return message;
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
if (pols_utils_1.PUtils.getType(wrapper.value) != 'Object') {
|
|
303
|
-
return message;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return { schema, prefix };
|
|
303
|
+
return isObject(wrapper, schema, prefix);
|
|
307
304
|
});
|
|
308
305
|
}
|
|
309
306
|
isBoolean() {
|
|
310
|
-
this.add(this.isBoolean.name, (wrapper) => {
|
|
307
|
+
return this.add(this.isBoolean.name, (wrapper) => {
|
|
311
308
|
const message = `'${wrapper.label}' debe ser de tipo booleano`;
|
|
312
309
|
if (typeof wrapper.value == 'string') {
|
|
313
310
|
const value = wrapper.value.trim().toUpperCase();
|
|
@@ -355,7 +352,6 @@ class Rules extends rulesEngine_1.RulesEngine {
|
|
|
355
352
|
return typeof wrapper.value == 'boolean' ? null : message;
|
|
356
353
|
}
|
|
357
354
|
});
|
|
358
|
-
return this;
|
|
359
355
|
}
|
|
360
356
|
upper() {
|
|
361
357
|
this.isAlphanumeric();
|
package/dist/rulesEngine.d.ts
CHANGED
|
@@ -5,10 +5,7 @@ export type RulesParams = {
|
|
|
5
5
|
} | {
|
|
6
6
|
default?: unknown;
|
|
7
7
|
});
|
|
8
|
-
export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | void | null | undefined
|
|
9
|
-
schema: Record<string, RulesEngine>;
|
|
10
|
-
prefix?: string;
|
|
11
|
-
};
|
|
8
|
+
export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | string[] | void | null | undefined;
|
|
12
9
|
export type Wrapper<T = unknown> = {
|
|
13
10
|
value: T;
|
|
14
11
|
label: string;
|
|
@@ -18,7 +15,7 @@ export declare class RulesEngine {
|
|
|
18
15
|
label: string;
|
|
19
16
|
required: boolean;
|
|
20
17
|
default: unknown;
|
|
21
|
-
collection:
|
|
22
|
-
protected add(name: string, validationFunction: ValidationFunction): this;
|
|
18
|
+
collection: ValidationFunction[];
|
|
19
|
+
protected add(name: string, validationFunction: ValidationFunction, executeOnce?: boolean): this;
|
|
23
20
|
}
|
|
24
21
|
//# sourceMappingURL=rulesEngine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rulesEngine.d.ts","sourceRoot":"","sources":["../src/rulesEngine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,CAAC;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"rulesEngine.d.ts","sourceRoot":"","sources":["../src/rulesEngine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,CAAC;IACJ,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAA;AAEtH,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,IAAI;IAClC,KAAK,EAAE,CAAC,CAAA;IACR,KAAK,EAAE,MAAM,CAAA;CACb,CAAA;AAED,qBAAa,WAAW;gBACX,MAAM,CAAC,EAAE,WAAW;IAOhC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAQ;IACzB,OAAO,EAAE,OAAO,CAAO;IACvB,UAAU,EAAE,kBAAkB,EAAE,CAAK;IAErC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,UAAQ;CAIvF"}
|
package/dist/rulesEngine.js
CHANGED
|
@@ -12,10 +12,9 @@ class RulesEngine {
|
|
|
12
12
|
label;
|
|
13
13
|
required = false;
|
|
14
14
|
default = null;
|
|
15
|
-
collection =
|
|
16
|
-
add(name, validationFunction) {
|
|
17
|
-
|
|
18
|
-
this.collection[name] = validationFunction;
|
|
15
|
+
collection = [];
|
|
16
|
+
add(name, validationFunction, executeOnce = false) {
|
|
17
|
+
this.collection.push(validationFunction);
|
|
19
18
|
return this;
|
|
20
19
|
}
|
|
21
20
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RulesEngine } from "./rulesEngine";
|
|
2
|
+
export type EvaluateResponse<T> = {
|
|
3
|
+
error: false;
|
|
4
|
+
success: true;
|
|
5
|
+
result: T;
|
|
6
|
+
} | {
|
|
7
|
+
error: true;
|
|
8
|
+
success: false;
|
|
9
|
+
messages: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare const validate: <T>(target: unknown, rules: RulesEngine) => EvaluateResponse<T>;
|
|
12
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAW,MAAM,eAAe,CAAA;AAEpD,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IACjC,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,IAAI,CAAA;IACb,MAAM,EAAE,CAAC,CAAA;CACT,GAAG;IACH,KAAK,EAAE,IAAI,CAAA;IACX,OAAO,EAAE,KAAK,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,UAAU,OAAO,SAAS,WAAW,KAAG,gBAAgB,CAAC,CAAC,CAoDnF,CAAA"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validate = void 0;
|
|
4
|
+
const pols_utils_1 = require("pols-utils");
|
|
5
|
+
const validate = (target, rules) => {
|
|
6
|
+
const errorMessages = [];
|
|
7
|
+
if (typeof target == 'string')
|
|
8
|
+
target = target.trim();
|
|
9
|
+
const isEmpty = target == null || (typeof target == 'string' && !target);
|
|
10
|
+
const label = rules.label ?? 'Este valor';
|
|
11
|
+
if (rules.required && isEmpty) {
|
|
12
|
+
return {
|
|
13
|
+
error: true,
|
|
14
|
+
success: false,
|
|
15
|
+
messages: [`'${label}' es requerido`]
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (isEmpty) {
|
|
19
|
+
return {
|
|
20
|
+
error: false,
|
|
21
|
+
success: true,
|
|
22
|
+
result: rules.default
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const wrapper = {
|
|
26
|
+
value: pols_utils_1.PUtils.clone(target),
|
|
27
|
+
label
|
|
28
|
+
};
|
|
29
|
+
for (const validationFunction of rules.collection) {
|
|
30
|
+
const result = validationFunction(wrapper);
|
|
31
|
+
if (!result)
|
|
32
|
+
continue;
|
|
33
|
+
if (typeof result == 'string') {
|
|
34
|
+
errorMessages.push(result);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
errorMessages.push(...result);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (errorMessages.length) {
|
|
42
|
+
return {
|
|
43
|
+
error: true,
|
|
44
|
+
success: false,
|
|
45
|
+
messages: errorMessages
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return {
|
|
50
|
+
error: false,
|
|
51
|
+
success: true,
|
|
52
|
+
result: wrapper.value
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
exports.validate = validate;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,87 +1,8 @@
|
|
|
1
|
-
import { PUtils } from "pols-utils"
|
|
2
1
|
import { Rules } from "./rules"
|
|
3
|
-
import {
|
|
4
|
-
export { RulesEngine } from './rulesEngine'
|
|
5
|
-
|
|
6
|
-
export type EvaluateResponse<T> = {
|
|
7
|
-
error: false
|
|
8
|
-
success: true
|
|
9
|
-
result: T
|
|
10
|
-
} | {
|
|
11
|
-
error: true
|
|
12
|
-
success: false
|
|
13
|
-
messages: string[]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const validate = <T>(target: unknown, rules: RulesEngine): EvaluateResponse<T> => {
|
|
17
|
-
const errorMessages: string[] = []
|
|
18
|
-
|
|
19
|
-
if (typeof target == 'string') target = target.trim()
|
|
20
|
-
|
|
21
|
-
const isEmpty = target == null || (typeof target == 'string' && !target)
|
|
22
|
-
const label = rules.label ?? 'Este valor'
|
|
23
|
-
|
|
24
|
-
if (rules.required && isEmpty) {
|
|
25
|
-
return {
|
|
26
|
-
error: true,
|
|
27
|
-
success: false,
|
|
28
|
-
messages: [`'${label}' es requerido`]
|
|
29
|
-
}
|
|
30
|
-
}
|
|
2
|
+
import { RulesParams } from "./rulesEngine"
|
|
31
3
|
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
error: false,
|
|
35
|
-
success: true,
|
|
36
|
-
result: rules.default as T
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const wrapper: Wrapper<T> = {
|
|
41
|
-
value: PUtils.clone(target) as T,
|
|
42
|
-
label
|
|
43
|
-
}
|
|
44
|
-
for (const validationFunction of Object.values(rules.collection)) {
|
|
45
|
-
const result = validationFunction(wrapper)
|
|
46
|
-
if (!result) continue
|
|
47
|
-
if (typeof result == 'string') {
|
|
48
|
-
errorMessages.push(result)
|
|
49
|
-
break
|
|
50
|
-
} else {
|
|
51
|
-
if (wrapper.value == null || typeof wrapper.value != 'object') throw new Error(`El valor no es un objeto para ser validado contra un esquema: ${wrapper.value}`)
|
|
52
|
-
|
|
53
|
-
const newResult: Record<string, unknown> = {}
|
|
54
|
-
for (const key in result.schema) {
|
|
55
|
-
const rulesInside = result.schema[key]
|
|
56
|
-
const labelIndise = rulesInside.label ?? key
|
|
57
|
-
rulesInside.label = `${result.prefix ? `${result.prefix} ` : ''}${labelIndise}`
|
|
58
|
-
|
|
59
|
-
newResult[key] = wrapper.value[key]
|
|
60
|
-
|
|
61
|
-
const result2 = validate(newResult[key], rulesInside)
|
|
62
|
-
if (result2.error == true) {
|
|
63
|
-
errorMessages.push(...result2.messages)
|
|
64
|
-
} else {
|
|
65
|
-
newResult[key] = result2.result
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
wrapper.value = newResult as T
|
|
69
|
-
}
|
|
70
|
-
}
|
|
4
|
+
export { RulesEngine } from './rulesEngine'
|
|
71
5
|
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
error: true,
|
|
75
|
-
success: false,
|
|
76
|
-
messages: errorMessages
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
return {
|
|
80
|
-
error: false,
|
|
81
|
-
success: true,
|
|
82
|
-
result: wrapper.value
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
6
|
+
export { EvaluateResponse, validate } from './validate'
|
|
86
7
|
|
|
87
8
|
export const rules = (params?: RulesParams) => new Rules(params)
|
package/src/rules.ts
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { PDate, PUtils } from "pols-utils"
|
|
2
2
|
import { RulesEngine, Wrapper } from "./rulesEngine"
|
|
3
|
+
import { validate } from "./validate"
|
|
4
|
+
|
|
5
|
+
const isObject = (wrapper: Wrapper, schema?: Record<string, RulesEngine>, prefix?: string) => {
|
|
6
|
+
const message = `'${wrapper.label}' debe ser un objeto`
|
|
7
|
+
|
|
8
|
+
if (typeof wrapper.value == 'string') {
|
|
9
|
+
try {
|
|
10
|
+
wrapper.value = JSON.parse(wrapper.value)
|
|
11
|
+
} catch {
|
|
12
|
+
return message
|
|
13
|
+
}
|
|
14
|
+
if (PUtils.getType(wrapper.value) != 'Object') return message
|
|
15
|
+
} else {
|
|
16
|
+
if (PUtils.getType(wrapper.value) != 'Object') {
|
|
17
|
+
return message
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Realiza la validación de cada propiedad */
|
|
22
|
+
const newWrapperValue: Record<string, unknown> = {}
|
|
23
|
+
const errorMessages: string[] = []
|
|
24
|
+
for (const key in schema) {
|
|
25
|
+
const rulesInside = schema[key]
|
|
26
|
+
const labelIndise = rulesInside.label ?? key
|
|
27
|
+
rulesInside.label = `${prefix ?? ''}${labelIndise}`
|
|
28
|
+
|
|
29
|
+
newWrapperValue[key] = wrapper.value[key]
|
|
30
|
+
|
|
31
|
+
const result2 = validate(newWrapperValue[key], rulesInside)
|
|
32
|
+
if (result2.error == true) {
|
|
33
|
+
errorMessages.push(...result2.messages)
|
|
34
|
+
} else {
|
|
35
|
+
newWrapperValue[key] = result2.result
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (errorMessages.length) {
|
|
39
|
+
return errorMessages
|
|
40
|
+
} else {
|
|
41
|
+
wrapper.value = newWrapperValue
|
|
42
|
+
}
|
|
43
|
+
}
|
|
3
44
|
|
|
4
45
|
export class Rules extends RulesEngine {
|
|
5
46
|
isAlphanumeric() {
|
|
@@ -112,110 +153,83 @@ export class Rules extends RulesEngine {
|
|
|
112
153
|
}
|
|
113
154
|
|
|
114
155
|
maxLength(limit: number) {
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
156
|
+
return this.add(this.maxLength.name, (wrapper: Wrapper) => {
|
|
157
|
+
if (wrapper.value instanceof Array) {
|
|
158
|
+
return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como máximo` : null
|
|
159
|
+
} else if (typeof wrapper.value == 'string') {
|
|
160
|
+
return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como máximo` : null
|
|
161
|
+
} else {
|
|
162
|
+
return `'${wrapper.label}' no es de un tipo válido`
|
|
163
|
+
}
|
|
118
164
|
})
|
|
119
|
-
return this
|
|
120
165
|
}
|
|
121
166
|
|
|
122
|
-
// maxCount(limit: number) {
|
|
123
|
-
// this.isArray()
|
|
124
|
-
// this.add(this.maxLength.name, (wrapper: Wrapper<unknown[]>) => {
|
|
125
|
-
// if (wrapper.value.length > limit) return `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elemento' : 'elementos'}' como máximo`
|
|
126
|
-
// })
|
|
127
|
-
// return this
|
|
128
|
-
// }
|
|
129
|
-
|
|
130
167
|
minLength(limit: number) {
|
|
131
|
-
this.
|
|
132
|
-
|
|
133
|
-
|
|
168
|
+
return this.add(this.minLength.name, (wrapper: Wrapper) => {
|
|
169
|
+
if (wrapper.value instanceof Array) {
|
|
170
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como mínimo` : null
|
|
171
|
+
} else if (typeof wrapper.value == 'string') {
|
|
172
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como mínimo` : null
|
|
173
|
+
} else {
|
|
174
|
+
return `'${wrapper.label}' no es de un tipo válido`
|
|
175
|
+
}
|
|
134
176
|
})
|
|
135
|
-
return this
|
|
136
177
|
}
|
|
137
178
|
|
|
138
|
-
|
|
139
|
-
this.
|
|
140
|
-
|
|
141
|
-
|
|
179
|
+
hasFixedLength(limit: number) {
|
|
180
|
+
return this.add(this.hasFixedLength.name, (wrapper: Wrapper) => {
|
|
181
|
+
if (wrapper.value instanceof Array) {
|
|
182
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'elementos' : 'elementos'}'` : null
|
|
183
|
+
} else if (typeof wrapper.value == 'string') {
|
|
184
|
+
return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}'` : null
|
|
185
|
+
} else {
|
|
186
|
+
return `'${wrapper.label}' no es de un tipo válido`
|
|
187
|
+
}
|
|
142
188
|
})
|
|
143
|
-
return this
|
|
144
189
|
}
|
|
145
190
|
|
|
146
191
|
left(limit: number) {
|
|
147
|
-
this.isAlphanumeric()
|
|
148
|
-
this.add(this.length.name, (wrapper: Wrapper) => {
|
|
192
|
+
return this.isAlphanumeric().add(this.left.name, (wrapper: Wrapper) => {
|
|
149
193
|
(wrapper.value as string) = (wrapper.value as string).substring(0, limit)
|
|
150
194
|
})
|
|
151
|
-
return this
|
|
152
195
|
}
|
|
153
196
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// wrapper.value = result
|
|
191
|
-
// }
|
|
192
|
-
// }
|
|
193
|
-
// })
|
|
194
|
-
// return this
|
|
195
|
-
// }
|
|
196
|
-
|
|
197
|
-
// isArrayOfObjects(checkingElements?: (i: number) => FieldsStructure, prefixString?: (i: number) => string) {
|
|
198
|
-
// this.isArray()
|
|
199
|
-
// this.add(this.isArrayOfObjects.name, (wrapper: Wrapper<unknown[]>) => {
|
|
200
|
-
// const message = `'${wrapper.label}' debe ser una lista de objetos`
|
|
201
|
-
// const messages: string[] = []
|
|
202
|
-
// for (const [i, v] of wrapper.value.entries()) {
|
|
203
|
-
// const result = isObject(v)
|
|
204
|
-
// if (result.error == true) return message
|
|
205
|
-
// wrapper.value[i] = result.result
|
|
206
|
-
// if (checkingElements) {
|
|
207
|
-
// const v = wrapper.validator(wrapper.value[i], checkingElements(i), prefixString?.(i))
|
|
208
|
-
// if (v.error == true) {
|
|
209
|
-
// messages.push(...v.messages)
|
|
210
|
-
// } else {
|
|
211
|
-
// wrapper.value[i] = v.result
|
|
212
|
-
// }
|
|
213
|
-
// }
|
|
214
|
-
// }
|
|
215
|
-
// if (messages.length) return messages
|
|
216
|
-
// })
|
|
217
|
-
// return this
|
|
218
|
-
// }
|
|
197
|
+
isArray() {
|
|
198
|
+
return this.add(this.isArray.name, (wrapper: Wrapper) => {
|
|
199
|
+
const message = `'${wrapper.label}' debe ser una lista de elementos`
|
|
200
|
+
if (typeof wrapper.value == 'string') {
|
|
201
|
+
try {
|
|
202
|
+
const value = JSON.parse(wrapper.value)
|
|
203
|
+
if (!(value instanceof Array)) return message
|
|
204
|
+
wrapper.value = value
|
|
205
|
+
} catch (err) {
|
|
206
|
+
return message
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
if (!(wrapper.value instanceof Array)) return message
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
isArrayOfObjects(schema?: (index: number) => Record<string, RulesEngine>, prefix?: (index: number) => string) {
|
|
215
|
+
return this.isArray().add(this.isArrayOfObjects.name, (wrapper: Wrapper<unknown[]>) => {
|
|
216
|
+
const messages: string[] = []
|
|
217
|
+
for (const [i, value] of wrapper.value.entries()) {
|
|
218
|
+
const v = isObject({
|
|
219
|
+
label: prefix?.(i) ?? `Item ${i}`,
|
|
220
|
+
value
|
|
221
|
+
}, schema?.(i))
|
|
222
|
+
if (v) {
|
|
223
|
+
if (v instanceof Array) {
|
|
224
|
+
messages.push(...v)
|
|
225
|
+
} else {
|
|
226
|
+
messages.push(v)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (messages.length) return messages
|
|
231
|
+
})
|
|
232
|
+
}
|
|
219
233
|
|
|
220
234
|
isIn(...elements: unknown[]) {
|
|
221
235
|
this.add(this.isIn.name, (wrapper: Wrapper) => {
|
|
@@ -237,78 +251,51 @@ export class Rules extends RulesEngine {
|
|
|
237
251
|
return this
|
|
238
252
|
}
|
|
239
253
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// return this
|
|
246
|
-
// }
|
|
254
|
+
hasElements() {
|
|
255
|
+
return this.isArray().add(this.hasElements.name, (wrapper: Wrapper<unknown[]>) => {
|
|
256
|
+
if (!wrapper.value.length) return `'${wrapper.label}' debe contenedor al menos un elemento`
|
|
257
|
+
})
|
|
258
|
+
}
|
|
247
259
|
|
|
248
260
|
gt(limit: number) {
|
|
249
|
-
this.isNumber()
|
|
250
|
-
this.add(this.gt.name, (wrapper: Wrapper) => {
|
|
261
|
+
return this.isNumber().add(this.gt.name, (wrapper: Wrapper) => {
|
|
251
262
|
if (wrapper.value as number <= limit) return `'${wrapper.label}' debe ser mayor a '${limit}'`
|
|
252
263
|
})
|
|
253
|
-
return this
|
|
254
264
|
}
|
|
255
265
|
|
|
256
266
|
gte(limit: number) {
|
|
257
|
-
this.isNumber()
|
|
258
|
-
this.add(this.gte.name, (wrapper: Wrapper) => {
|
|
267
|
+
return this.isNumber().add(this.gte.name, (wrapper: Wrapper) => {
|
|
259
268
|
if (wrapper.value as number < limit) return `'${wrapper.label}' debe ser mayor o igual a '${limit}'`
|
|
260
269
|
})
|
|
261
|
-
return this
|
|
262
270
|
}
|
|
263
271
|
|
|
264
272
|
lt(limit: number) {
|
|
265
|
-
this.isNumber()
|
|
266
|
-
this.add(this.lt.name, (wrapper: Wrapper) => {
|
|
273
|
+
return this.isNumber().add(this.lt.name, (wrapper: Wrapper) => {
|
|
267
274
|
if (wrapper.value as number >= limit) return `'${wrapper.label}' debe ser menor a '${limit}'`
|
|
268
275
|
})
|
|
269
|
-
return this
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
lte(limit: number) {
|
|
273
|
-
return this
|
|
274
|
-
.
|
|
275
|
-
|
|
276
|
-
if (wrapper.value as number > limit) return `'${wrapper.label}' debe ser menor o igual a '${limit}'`
|
|
277
|
-
})
|
|
279
|
+
return this.isNumber().add(this.lte.name, (wrapper: Wrapper) => {
|
|
280
|
+
if (wrapper.value as number > limit) return `'${wrapper.label}' debe ser menor o igual a '${limit}'`
|
|
281
|
+
})
|
|
278
282
|
}
|
|
279
283
|
|
|
280
284
|
beforeOrSameAsNow() {
|
|
281
|
-
return this
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (wrapper.value.time > now.time) return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`
|
|
286
|
-
})
|
|
285
|
+
return this.isDateTime().add(this.beforeOrSameAsNow.name, (wrapper: Wrapper<PDate>) => {
|
|
286
|
+
const now = new PDate
|
|
287
|
+
if (wrapper.value.time > now.time) return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`
|
|
288
|
+
})
|
|
287
289
|
}
|
|
288
290
|
|
|
289
291
|
isObject(schema?: Record<string, RulesEngine>, prefix?: string) {
|
|
290
292
|
return this.add(this.isObject.name, (wrapper: Wrapper) => {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (typeof wrapper.value == 'string') {
|
|
294
|
-
try {
|
|
295
|
-
wrapper.value = JSON.parse(wrapper.value)
|
|
296
|
-
} catch {
|
|
297
|
-
return message
|
|
298
|
-
}
|
|
299
|
-
if (PUtils.getType(wrapper.value) != 'Object') return message
|
|
300
|
-
} else {
|
|
301
|
-
if (PUtils.getType(wrapper.value) != 'Object') {
|
|
302
|
-
return message
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return { schema, prefix }
|
|
293
|
+
return isObject(wrapper, schema, prefix)
|
|
307
294
|
})
|
|
308
295
|
}
|
|
309
296
|
|
|
310
297
|
isBoolean() {
|
|
311
|
-
this.add(this.isBoolean.name, (wrapper: Wrapper) => {
|
|
298
|
+
return this.add(this.isBoolean.name, (wrapper: Wrapper) => {
|
|
312
299
|
const message = `'${wrapper.label}' debe ser de tipo booleano`
|
|
313
300
|
if (typeof wrapper.value == 'string') {
|
|
314
301
|
const value = wrapper.value.trim().toUpperCase()
|
|
@@ -352,7 +339,6 @@ export class Rules extends RulesEngine {
|
|
|
352
339
|
return typeof wrapper.value == 'boolean' ? null : message
|
|
353
340
|
}
|
|
354
341
|
})
|
|
355
|
-
return this
|
|
356
342
|
}
|
|
357
343
|
|
|
358
344
|
upper() {
|
package/src/rulesEngine.ts
CHANGED
|
@@ -6,10 +6,7 @@ export type RulesParams = {
|
|
|
6
6
|
default?: unknown
|
|
7
7
|
})
|
|
8
8
|
|
|
9
|
-
export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | void | null | undefined
|
|
10
|
-
schema: Record<string, RulesEngine>
|
|
11
|
-
prefix?: string
|
|
12
|
-
}
|
|
9
|
+
export type ValidationFunction = (wrapper: Wrapper, ...args: unknown[]) => string | string[] | void | null | undefined
|
|
13
10
|
|
|
14
11
|
export type Wrapper<T = unknown> = {
|
|
15
12
|
value: T
|
|
@@ -27,10 +24,10 @@ export class RulesEngine {
|
|
|
27
24
|
label: string
|
|
28
25
|
required: boolean = false
|
|
29
26
|
default: unknown = null
|
|
30
|
-
collection:
|
|
27
|
+
collection: ValidationFunction[] = []
|
|
31
28
|
|
|
32
|
-
protected add(name: string, validationFunction: ValidationFunction) {
|
|
33
|
-
|
|
29
|
+
protected add(name: string, validationFunction: ValidationFunction, executeOnce = false) {
|
|
30
|
+
this.collection.push(validationFunction)
|
|
34
31
|
return this
|
|
35
32
|
}
|
|
36
33
|
}
|
package/src/validate.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { PUtils } from "pols-utils"
|
|
2
|
+
import { RulesEngine, Wrapper } from "./rulesEngine"
|
|
3
|
+
|
|
4
|
+
export type EvaluateResponse<T> = {
|
|
5
|
+
error: false
|
|
6
|
+
success: true
|
|
7
|
+
result: T
|
|
8
|
+
} | {
|
|
9
|
+
error: true
|
|
10
|
+
success: false
|
|
11
|
+
messages: string[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const validate = <T>(target: unknown, rules: RulesEngine): EvaluateResponse<T> => {
|
|
15
|
+
const errorMessages: string[] = []
|
|
16
|
+
|
|
17
|
+
if (typeof target == 'string') target = target.trim()
|
|
18
|
+
|
|
19
|
+
const isEmpty = target == null || (typeof target == 'string' && !target)
|
|
20
|
+
const label = rules.label ?? 'Este valor'
|
|
21
|
+
|
|
22
|
+
if (rules.required && isEmpty) {
|
|
23
|
+
return {
|
|
24
|
+
error: true,
|
|
25
|
+
success: false,
|
|
26
|
+
messages: [`'${label}' es requerido`]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (isEmpty) {
|
|
31
|
+
return {
|
|
32
|
+
error: false,
|
|
33
|
+
success: true,
|
|
34
|
+
result: rules.default as T
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const wrapper: Wrapper<T> = {
|
|
39
|
+
value: PUtils.clone(target) as T,
|
|
40
|
+
label
|
|
41
|
+
}
|
|
42
|
+
for (const validationFunction of rules.collection) {
|
|
43
|
+
const result = validationFunction(wrapper)
|
|
44
|
+
if (!result) continue
|
|
45
|
+
if (typeof result == 'string') {
|
|
46
|
+
errorMessages.push(result)
|
|
47
|
+
break
|
|
48
|
+
} else {
|
|
49
|
+
errorMessages.push(...result)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (errorMessages.length) {
|
|
54
|
+
return {
|
|
55
|
+
error: true,
|
|
56
|
+
success: false,
|
|
57
|
+
messages: errorMessages
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
return {
|
|
61
|
+
error: false,
|
|
62
|
+
success: true,
|
|
63
|
+
result: wrapper.value
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|