pols-validator 2.4.3 → 2.4.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAA;AA6C3D,qBAAa,MAAO,SAAQ,YAAY;IACvC,cAAc;IAWd,cAAc;IAQd,UAAU;IAUV,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,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IAiClD,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAY3B,OAAO,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAM9B,WAAW;IAMX,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,KAAK,CAAC,KAAK,EAAE,MAAM;IAMnB,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,KAAK,CAAC,KAAK,EAAE,MAAM;IAMnB,iBAAiB;IAOjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxC,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;IAMhC,IAAI,CAAC,SAAS,EAAE,MAAM;IAMtB,KAAK;IAML,IAAI;IAMJ,QAAQ,CAAC,GAAG,WAAW,EAAE,MAAM,EAAE;CAKjC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAA;AA2C3D,qBAAa,MAAO,SAAQ,YAAY;IACvC,cAAc;IAWd,cAAc;IAQd,UAAU;IAUV,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,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IAiClD,IAAI,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAY3B,OAAO,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE;IAM9B,WAAW;IAMX,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,KAAK,CAAC,KAAK,EAAE,MAAM;IAMnB,IAAI,CAAC,KAAK,EAAE,MAAM;IAMlB,KAAK,CAAC,KAAK,EAAE,MAAM;IAMnB,iBAAiB;IAOjB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxC,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;IAMhC,IAAI,CAAC,SAAS,EAAE,MAAM;IAMtB,KAAK;IAML,IAAI;IAMJ,QAAQ,CAAC,GAAG,WAAW,EAAE,MAAM,EAAE;CAKjC"}
package/dist/rules.js CHANGED
@@ -31,13 +31,12 @@ const isObject = (context, wrapper, schema) => {
31
31
  const rulesInside = schema[key];
32
32
  const labelIndise = rulesInside.label ?? key;
33
33
  rulesInside.label = `${context.label ? `${context.label}${context.separator}` : ''}${labelIndise}`;
34
- newWrapperValue[key] = wrapper.value[key];
35
- const result2 = rulesInside.validate(newWrapperValue[key], false);
34
+ const result2 = rulesInside.validate(wrapper.value[key], false);
36
35
  if (result2.error == true) {
37
36
  errorMessages.push(...result2.messages);
38
37
  }
39
38
  else {
40
- if (result2 !== undefined)
39
+ if (result2.result !== undefined)
41
40
  newWrapperValue[key] = result2.result;
42
41
  }
43
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pols-validator",
3
- "version": "2.4.3",
3
+ "version": "2.4.5",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts DELETED
@@ -1,8 +0,0 @@
1
- import { PRules } from "./rules"
2
- import { PRulesParams } from "./rulesEngine"
3
-
4
- export const rules = (params?: PRulesParams) => new PRules(params)
5
-
6
- export { PRules, PRulesParams }
7
-
8
- export { PRulesResponse, PRulesWrapper, PRulesFunction } from './rulesEngine'
package/src/rules.ts DELETED
@@ -1,428 +0,0 @@
1
- import { PRulesEngine, PRulesWrapper } from "./rulesEngine"
2
- import { PDate } from "pols-date"
3
- import { sanitize } from 'isomorphic-dompurify'
4
- import { PUtilsNumber, PUtilsString } from "pols-utils"
5
-
6
- const isObject = (context: PRules, wrapper: PRulesWrapper, schema?: Record<string, PRules>) => {
7
- const message = `'${wrapper.label}' debe ser un objeto`
8
-
9
- if (typeof wrapper.value == 'string') {
10
- try {
11
- wrapper.value = JSON.parse(wrapper.value)
12
- } catch {
13
- return message
14
- }
15
- if (wrapper.value == null || typeof wrapper.value != 'object') return message
16
- } else if (wrapper.value != null) {
17
- if (typeof wrapper.value != 'object') return message
18
- } else {
19
- return message
20
- }
21
-
22
- /* Realiza la validación de cada propiedad */
23
- const newWrapperValue: Record<string, unknown> = {}
24
- const errorMessages: string[] = []
25
- for (const key in schema) {
26
- const rulesInside = schema[key]
27
- const labelIndise = rulesInside.label ?? key
28
- rulesInside.label = `${context.label ? `${context.label}${context.separator}` : ''}${labelIndise}`
29
-
30
- newWrapperValue[key] = wrapper.value[key]
31
-
32
- const result2 = rulesInside.validate(newWrapperValue[key], false)
33
- if (result2.error == true) {
34
- errorMessages.push(...result2.messages)
35
- } else {
36
- if (result2 !== undefined) newWrapperValue[key] = result2.result
37
- }
38
- }
39
- if (errorMessages.length) {
40
- return errorMessages
41
- } else {
42
- wrapper.value = newWrapperValue
43
- }
44
- }
45
-
46
- export class PRules extends PRulesEngine {
47
- isAlphanumeric() {
48
- this.add(this.isAlphanumeric.name, (wrapper: PRulesWrapper) => {
49
- if (typeof wrapper.value == 'number') {
50
- wrapper.value = wrapper.value.toString()
51
- } else if (typeof wrapper.value != 'string') {
52
- return `'${wrapper.label}' debe ser un alfanumérico`
53
- }
54
- })
55
- return this
56
- }
57
-
58
- isEmailAddress() {
59
- this.isAlphanumeric()
60
- this.add(this.isEmailAddress.name, (wrapper: PRulesWrapper) => {
61
- if (!(wrapper.value as string).match(/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/)) return `'${wrapper.label}' debe ser una dirección de correo`
62
- })
63
- return this
64
- }
65
-
66
- isDateTime() {
67
- this.add(this.isDateTime.name, (wrapper: PRulesWrapper) => {
68
- const message = `'${wrapper.label}' tiene un formato de fecha y hora no válido`
69
- const newDate = new PDate(wrapper.value)
70
- if (newDate.isInvalidDate) return message
71
- wrapper.value = newDate
72
- })
73
- return this
74
- }
75
-
76
- isDate() {
77
- return this.isDateTime().add(this.isDate.name, (wrapper: PRulesWrapper<PDate>) => {
78
- wrapper.value.clearClockTime()
79
- })
80
- }
81
-
82
- isTime() {
83
- this.add(this.isTime.name, (wrapper: PRulesWrapper) => {
84
- const message = `'${wrapper.label}' contiene un formato de hora no válido`
85
- const value = wrapper.value.toString()
86
- const parts = value.replace(/[.,]/g, ':').replace('m', '').match(/^([0-2]?[0-9])(:?)([0-5]?[0-9]?)(:?)([0-5]?[0-9]?)([ap]?)\.?m?\.?$/)
87
- if (!parts) return message
88
- let hours = Number(parts[1])
89
- const minutes = Number(parts[3])
90
- const seconds = Number(parts[5])
91
- const middle = parts[6]
92
- if (minutes < 60 && seconds < 60) {
93
- /* Si middle es diferente de vacío, es porque el usuario tiene la intención de especificar una hora del día, caso contrario, está indicando una duración. */
94
- if (middle) {
95
- if (hours >= 1 && hours <= 12) {
96
- if (middle === 'p') hours += 12
97
- wrapper.value = `${PUtilsString.padStart(hours, 2)}:${PUtilsString.padStart(minutes, 2)}:${PUtilsString.padStart(seconds, 2)}`
98
- return
99
- }
100
- } else if (hours >= 0 && hours <= 23) {
101
- wrapper.value = `${PUtilsString.padStart(hours, 2)}:${PUtilsString.padStart(minutes, 2)}:${PUtilsString.padStart(seconds, 2)}`
102
- return
103
- }
104
- }
105
- return message
106
- })
107
- return this
108
- }
109
-
110
- match(pattern: RegExp) {
111
- this.isAlphanumeric()
112
- this.add(this.match.name, (wrapper: PRulesWrapper) => {
113
- if (!(wrapper.value as string).match(pattern)) return `'${wrapper.label}' no cumple con el formato de texto deseado`
114
- })
115
- return this
116
- }
117
-
118
- isNumber() {
119
- this.add(this.isNumber.name, (wrapper: PRulesWrapper) => {
120
- const message = `'${wrapper.label}' debe ser un número`
121
- const value = Number(wrapper.value)
122
- if (isNaN(value) || value == Infinity) return message
123
- wrapper.value = value
124
- })
125
- return this
126
- }
127
-
128
- isInteger() {
129
- this.isNumber()
130
- this.add(this.isInteger.name, (wrapper: PRulesWrapper) => {
131
- if (wrapper.value != Math.floor(wrapper.value as number)) return `'${wrapper.label}' debe ser un número entero`
132
- })
133
- return this
134
- }
135
-
136
- isNatural() {
137
- return this.isInteger().isGte(0)
138
- }
139
-
140
- isNaturalNoZero() {
141
- return this.isInteger().isGt(0)
142
- }
143
-
144
- onlyNumbers() {
145
- this.isAlphanumeric()
146
- this.add(this.onlyNumbers.name, (wrapper: PRulesWrapper) => {
147
- if (!(wrapper.value as string).match(/^[0-9]+$/)) return `'${wrapper.label}' debe contener sólo números`
148
- })
149
- return this
150
- }
151
-
152
- maxLength(limit: number) {
153
- return this.add(this.maxLength.name, (wrapper: PRulesWrapper) => {
154
- if (wrapper.value instanceof Array) {
155
- return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como máximo` : null
156
- } else if (typeof wrapper.value == 'string') {
157
- return wrapper.value.length > limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como máximo` : null
158
- } else {
159
- return `'${wrapper.label}' no es de un tipo válido`
160
- }
161
- })
162
- }
163
-
164
- minLength(limit: number) {
165
- return this.add(this.minLength.name, (wrapper: PRulesWrapper) => {
166
- if (wrapper.value instanceof Array) {
167
- return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'elementos' : 'elementos'}' como mínimo` : null
168
- } else if (typeof wrapper.value == 'string') {
169
- return wrapper.value.length < limit ? `'${wrapper.label}' debe contener '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}' como mínimo` : null
170
- } else {
171
- return `'${wrapper.label}' no es de un tipo válido`
172
- }
173
- })
174
- }
175
-
176
- hasFixedLength(limit: number) {
177
- return this.add(this.hasFixedLength.name, (wrapper: PRulesWrapper) => {
178
- if (wrapper.value instanceof Array) {
179
- return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'elementos' : 'elementos'}'` : null
180
- } else if (typeof wrapper.value == 'string') {
181
- return wrapper.value.length < limit ? `'${wrapper.label}' debe contener sólo '${limit} ${limit == 1 ? 'caracter' : 'caracteres'}'` : null
182
- } else {
183
- return `'${wrapper.label}' no es de un tipo válido`
184
- }
185
- })
186
- }
187
-
188
- left(limit: number) {
189
- return this.isAlphanumeric().add(this.left.name, (wrapper: PRulesWrapper) => {
190
- (wrapper.value as string) = (wrapper.value as string).substring(0, limit)
191
- })
192
- }
193
-
194
- isArray(rulesGenerator?: (index: number) => PRules) {
195
- return this.add(this.isArray.name, (wrapper: PRulesWrapper<unknown[]>) => {
196
- const message = `'${wrapper.label}' debe ser una lista de elementos`
197
- if (typeof wrapper.value == 'string') {
198
- try {
199
- const value = JSON.parse(wrapper.value)
200
- if (!(value instanceof Array)) return message
201
- wrapper.value = value
202
- } catch (err) {
203
- return message
204
- }
205
- } else {
206
- if (!(wrapper.value instanceof Array)) return message
207
- }
208
-
209
- if (!rulesGenerator) return
210
-
211
- /* Si se ha definido un generador de reglas, se itera cada elemento */
212
- const messages: string[] = []
213
- for (const [i, element] of wrapper.value.entries()) {
214
- const rules = rulesGenerator(i)
215
- rules.label = `${this.label ? `${this.label}${rules.label ? this.separator : ''}` : ''}${rules.label ?? ''}`
216
- const result = rules.validate(element, false)
217
- if (result.error == true) {
218
- messages.push(...result.messages)
219
- } else {
220
- wrapper.value[i] = result.result
221
- }
222
- }
223
- if (messages.length) return messages
224
- })
225
- }
226
-
227
- isIn(...elements: unknown[]) {
228
- return this.add(this.isIn.name, (wrapper: PRulesWrapper) => {
229
- if (wrapper.value instanceof Array) {
230
- for (const v of wrapper.value) {
231
- if (!elements.includes(v)) return `'${wrapper.label}' no contiene valores válidos`
232
- }
233
- } else {
234
- if (!elements.includes(wrapper.value)) return `'${wrapper.label}' no tiene un valor válido`
235
- }
236
- })
237
- }
238
-
239
- isNotIn(...elements: unknown[]) {
240
- return this.add(this.isNotIn.name, (wrapper: PRulesWrapper) => {
241
- if (elements.includes(wrapper.value)) return `'${wrapper.label}' no tiene un valor válido`
242
- })
243
- }
244
-
245
- hasElements() {
246
- return this.isArray().add(this.hasElements.name, (wrapper: PRulesWrapper<unknown[]>) => {
247
- if (!wrapper.value.length) return `'${wrapper.label}' debe contenedor al menos un elemento`
248
- })
249
- }
250
-
251
- isGt(limit: number) {
252
- return this.isNumber().add(this.isGt.name, (wrapper: PRulesWrapper) => {
253
- if (wrapper.value as number <= limit) return `'${wrapper.label}' debe ser mayor a '${limit}'`
254
- })
255
- }
256
-
257
- isGte(limit: number) {
258
- return this.isNumber().add(this.isGte.name, (wrapper: PRulesWrapper) => {
259
- if (wrapper.value as number < limit) return `'${wrapper.label}' debe ser mayor o igual a '${limit}'`
260
- })
261
- }
262
-
263
- isLt(limit: number) {
264
- return this.isNumber().add(this.isLt.name, (wrapper: PRulesWrapper) => {
265
- if (wrapper.value as number >= limit) return `'${wrapper.label}' debe ser menor a '${limit}'`
266
- })
267
- }
268
-
269
- isLte(limit: number) {
270
- return this.isNumber().add(this.isLte.name, (wrapper: PRulesWrapper) => {
271
- if (wrapper.value as number > limit) return `'${wrapper.label}' debe ser menor o igual a '${limit}'`
272
- })
273
- }
274
-
275
- beforeOrSameAsNow() {
276
- return this.isDateTime().add(this.beforeOrSameAsNow.name, (wrapper: PRulesWrapper<PDate>) => {
277
- const now = new PDate
278
- if (wrapper.value.timestamp > now.timestamp) return `'${wrapper.label}' debe ser anterior o igual a 'ahora'`
279
- })
280
- }
281
-
282
- isObject(schema?: Record<string, PRules>) {
283
- return this.add(this.isObject.name, (wrapper: PRulesWrapper) => {
284
- return isObject(this, wrapper, schema)
285
- })
286
- }
287
-
288
- isBoolean() {
289
- return this.add(this.isBoolean.name, (wrapper: PRulesWrapper) => {
290
- const message = `'${wrapper.label}' debe ser de tipo booleano`
291
- if (typeof wrapper.value == 'string') {
292
- const value = wrapper.value.trim().toUpperCase()
293
- switch (value) {
294
- case '1':
295
- case 'S':
296
- case 'SÍ':
297
- case 'Y':
298
- case 'YES':
299
- wrapper.value = true
300
- return
301
- case '0':
302
- case 'N':
303
- case 'NO':
304
- wrapper.value = false
305
- return
306
- default: {
307
- let json
308
- try {
309
- json = JSON.parse(wrapper.value)
310
- } catch {
311
- return message
312
- }
313
- if (typeof json != 'boolean' && !([0, 1]).includes(json)) return message
314
- wrapper.value = json
315
- return
316
- }
317
- }
318
- } else if (typeof wrapper.value == 'number') {
319
- switch (wrapper.value) {
320
- case 0:
321
- wrapper.value = false
322
- return
323
- case 1:
324
- wrapper.value = true
325
- return
326
- default:
327
- return message
328
- }
329
- } else {
330
- return typeof wrapper.value == 'boolean' ? null : message
331
- }
332
- })
333
- }
334
-
335
- upper() {
336
- this.isAlphanumeric()
337
- this.add(this.upper.name, (wrapper: PRulesWrapper) => {
338
- wrapper.value = (wrapper.value as string).toUpperCase()
339
- })
340
- return this
341
- }
342
-
343
- lower() {
344
- this.isAlphanumeric()
345
- this.add(this.lower.name, (wrapper: PRulesWrapper) => {
346
- wrapper.value = (wrapper.value as string).toLowerCase()
347
- })
348
- return this
349
- }
350
-
351
- decodeURI() {
352
- this.isAlphanumeric()
353
- this.add(this.decodeURI.name, (wrapper: PRulesWrapper) => {
354
- wrapper.value = decodeURI(wrapper.value as string)
355
- })
356
- return this
357
- }
358
-
359
- round(decimals: number) {
360
- this.isNumber()
361
- this.add(this.round.name, (wrapper: PRulesWrapper) => {
362
- wrapper.value = PUtilsNumber.round(wrapper.value as number, decimals)
363
- })
364
- return this
365
- }
366
-
367
- /* Reemplaza todos los dobles (o más) espacios juntos por uno simple */
368
- cleanDoubleSpaces() {
369
- this.isAlphanumeric()
370
- this.add(this.cleanDoubleSpaces.name, (wrapper: PRulesWrapper) => {
371
- wrapper.value = (wrapper.value as string).replace(/\s{2,}/g, ' ')
372
- })
373
- return this
374
- }
375
-
376
- noSpaces() {
377
- this.isAlphanumeric()
378
- this.add(this.noSpaces.name, (wrapper: PRulesWrapper) => {
379
- if ((wrapper.value as string).match(/\s/)) return `'${wrapper.label}' no debe contener 'espacios'`
380
- })
381
- return this
382
- }
383
-
384
-
385
- replace(search: string | RegExp, replace: string | ((substring: string, ...args: any[]) => string)) {
386
- return this.isAlphanumeric().add(this.replace.name, (wrapper: PRulesWrapper) => {
387
- wrapper.value = (wrapper.value as string).replace(search, replace as any)
388
- })
389
- }
390
-
391
- capitalize() {
392
- this.isAlphanumeric()
393
- this.add(this.capitalize.name, (wrapper: PRulesWrapper) => {
394
- wrapper.value = PUtilsString.capitalize(wrapper.value as string)
395
- })
396
- return this
397
- }
398
-
399
- split(separator: string | RegExp) {
400
- return this.isAlphanumeric().add(this.split.name, (wrapper: PRulesWrapper<string>) => {
401
- wrapper.value = wrapper.value.split(separator) as any
402
- })
403
- }
404
-
405
- join(separator: string) {
406
- return this.isArray().add(this.join.name, (wrapper: PRulesWrapper<unknown[]>) => {
407
- wrapper.value = wrapper.value.join(separator) as any
408
- })
409
- }
410
-
411
- floor() {
412
- return this.isNumber().add(this.floor.name, (wrapper: PRulesWrapper<number>) => {
413
- wrapper.value = Math.floor(wrapper.value)
414
- })
415
- }
416
-
417
- ceil() {
418
- return this.isNumber().add(this.ceil.name, (wrapper: PRulesWrapper<number>) => {
419
- wrapper.value = Math.ceil(wrapper.value)
420
- })
421
- }
422
-
423
- sanitize(...allowedTags: string[]) {
424
- return this.isAlphanumeric().add(this.sanitize.name, (wrapper: PRulesWrapper) => {
425
- wrapper.value = sanitize((wrapper.value as string).trim(), { ALLOWED_TAGS: allowedTags })
426
- })
427
- }
428
- }
@@ -1,111 +0,0 @@
1
- export type PRulesParams = {
2
- label?: string
3
- separator?: string
4
- } & ({
5
- required?: boolean
6
- } | {
7
- default?: unknown
8
- })
9
-
10
- export type PRulesFunction = (wrapper: PRulesWrapper, ...args: unknown[]) => string | string[] | void | null | undefined
11
-
12
- export type PRulesWrapper<T = unknown> = {
13
- value: T
14
- label: string
15
- }
16
-
17
- export type PRulesResponse<T> = {
18
- error: false
19
- success: true
20
- result: T
21
- } | {
22
- error: true
23
- success: false
24
- messages: string[]
25
- }
26
-
27
- export class PRulesEngine {
28
- prefix: string
29
- label: string
30
- separator: string
31
- required: boolean = false
32
- default: unknown = null
33
-
34
- private collectionFunctions: PRulesFunction[] = []
35
- private collectionNames: string[] = []
36
-
37
- constructor(params?: PRulesParams) {
38
- this.label = params?.label
39
- this.separator = params?.separator ?? ' > '
40
- this.required = params && 'required' in params ? params?.required : false
41
- this.default = params && 'default' in params ? params?.default : null
42
- }
43
-
44
- protected add(name: string, validationFunction: PRulesFunction) {
45
- if (!this.collectionNames.includes(name)) {
46
- this.collectionNames.push(name)
47
- this.collectionFunctions.push(validationFunction)
48
- }
49
- return this
50
- }
51
-
52
- validate<T>(target: unknown, safe = true): PRulesResponse<T> {
53
- const errorMessages: string[] = []
54
-
55
- if (typeof target == 'string') target = target.trim()
56
-
57
- const defaultIsEmpty = this.default == null || (typeof this.default == 'string' && !this.default)
58
- const isEmpty = target == null || (typeof target == 'string' && !target)
59
-
60
- const label = this.label
61
-
62
- if (this.required && isEmpty) {
63
- return {
64
- error: true,
65
- success: false,
66
- messages: [`'${label}' es requerido`]
67
- }
68
- }
69
-
70
- if (isEmpty) {
71
- if (!defaultIsEmpty) {
72
- target = this.default
73
- } else {
74
- return {
75
- error: false,
76
- success: true,
77
- result: this.default as T
78
- }
79
- }
80
- }
81
-
82
- const wrapper: PRulesWrapper<T> = {
83
- value: safe ? JSON.parse(JSON.stringify(target)) : target,
84
- label
85
- }
86
- for (const validationFunction of this.collectionFunctions) {
87
- const result = validationFunction(wrapper)
88
- if (!result) continue
89
- if (typeof result == 'string') {
90
- errorMessages.push(result)
91
- break
92
- } else {
93
- errorMessages.push(...result)
94
- }
95
- }
96
-
97
- if (errorMessages.length) {
98
- return {
99
- error: true,
100
- success: false,
101
- messages: errorMessages
102
- }
103
- } else {
104
- return {
105
- error: false,
106
- success: true,
107
- result: wrapper.value
108
- }
109
- }
110
- }
111
- }