structure-verifier 0.0.17 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -329
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,32 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
Libreria de validacion para TypeScript orientada a esquemas declarativos, tipado inferido y errores detallados por ruta.
|
|
4
4
|
|
|
5
|
-
Ideal para validar payloads de API, formularios, configuraciones y estructuras anidadas
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
5
|
+
Ideal para validar payloads de API, formularios, configuraciones y estructuras anidadas.
|
|
6
|
+
|
|
7
|
+
## Objetivo de esta documentacion
|
|
8
|
+
|
|
9
|
+
Este README está diseñado para ayudarte a:
|
|
10
|
+
|
|
11
|
+
- Comprender rápidamente cómo funciona la librería.
|
|
12
|
+
- Integrarla de forma sencilla en un proyecto real.
|
|
13
|
+
- Conocer el contrato público de la API antes de utilizarla en producción.
|
|
14
|
+
- Explorar ejemplos prácticos de validación y tipado.
|
|
15
|
+
- Entender las decisiones de diseño y el enfoque de la librería.
|
|
16
|
+
|
|
17
|
+
## Tabla de contenido
|
|
18
|
+
|
|
19
|
+
- [Instalacion](#instalacion)
|
|
20
|
+
- [Inicio rapido](#inicio-rapido)
|
|
21
|
+
- [Conceptos clave](#conceptos-clave)
|
|
22
|
+
- [API publica](#api-publica)
|
|
23
|
+
- [Estilos de uso](#estilos-de-uso)
|
|
24
|
+
- [Validadores disponibles](#validadores-disponibles)
|
|
25
|
+
- [Transformaciones](#transformaciones)
|
|
26
|
+
- [Tipado inferido](#tipado-inferido)
|
|
27
|
+
- [Manejo de errores](#manejo-de-errores)
|
|
28
|
+
- [datetime (dayjs)](#datetime-dayjs)
|
|
29
|
+
- [Buenas practicas para v1.0.0](#buenas-practicas-para-v100)
|
|
30
|
+
- [Scripts de desarrollo](#scripts-de-desarrollo)
|
|
31
|
+
- [Licencia](#licencia)
|
|
31
32
|
|
|
32
33
|
## Instalacion
|
|
33
34
|
|
|
@@ -42,11 +43,11 @@ import { Verifiers as V, VerificationError } from "structure-verifier";
|
|
|
42
43
|
|
|
43
44
|
const userVerifier = V.ObjectNotNull(
|
|
44
45
|
{
|
|
45
|
-
id: V.
|
|
46
|
-
name: V.StringNotNull({ minLength: 2 }),
|
|
46
|
+
id: V.UUID({ version: 4 }).required(),
|
|
47
|
+
name: V.StringNotNull({ minLength: 2 }).trim(),
|
|
47
48
|
age: V.Number({ min: 0 }),
|
|
48
49
|
active: V.BooleanNotNull(),
|
|
49
|
-
tags: V.ArrayNotNull(V.StringNotNull()
|
|
50
|
+
tags: V.ArrayNotNull(V.StringNotNull(), { minLength: 1 }),
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
53
|
strictMode: true,
|
|
@@ -56,48 +57,64 @@ const userVerifier = V.ObjectNotNull(
|
|
|
56
57
|
try {
|
|
57
58
|
const user = userVerifier.check({
|
|
58
59
|
id: "550e8400-e29b-41d4-a716-446655440000",
|
|
59
|
-
name: "Ana",
|
|
60
|
+
name: " Ana ",
|
|
60
61
|
age: "31",
|
|
61
62
|
active: "true",
|
|
62
63
|
tags: ["admin"],
|
|
63
64
|
});
|
|
64
65
|
|
|
65
66
|
console.log(user);
|
|
67
|
+
// {
|
|
68
|
+
// id: "550e8400-e29b-41d4-a716-446655440000",
|
|
69
|
+
// name: "Ana",
|
|
70
|
+
// age: 31,
|
|
71
|
+
// active: true,
|
|
72
|
+
// tags: ["admin"]
|
|
73
|
+
// }
|
|
66
74
|
} catch (error) {
|
|
67
75
|
if (error instanceof VerificationError) {
|
|
68
|
-
console.
|
|
69
|
-
console.
|
|
70
|
-
console.
|
|
76
|
+
console.error(error.message);
|
|
77
|
+
console.error(error.errors);
|
|
78
|
+
console.error(error.errorsObj);
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
```
|
|
74
82
|
|
|
75
|
-
## Conceptos
|
|
83
|
+
## Conceptos clave
|
|
76
84
|
|
|
77
85
|
### 1) Nullable vs NotNull
|
|
78
86
|
|
|
79
|
-
- VNumber
|
|
80
|
-
-
|
|
81
|
-
-
|
|
87
|
+
- `VNumber`, `VString`, `VBoolean`, `VDate`, `VUUID`, `VArray`, `VObject` y `VAny` pueden devolver `null`.
|
|
88
|
+
- Las variantes `NotNull` devuelven siempre tipo requerido.
|
|
89
|
+
- En validadores nullable puedes promover a requerido con `.required()`.
|
|
82
90
|
|
|
83
|
-
### 2)
|
|
91
|
+
### 2) Inmutabilidad de reglas
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
Cada metodo de regla devuelve una nueva instancia del validador.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const base = V.StringNotNull();
|
|
97
|
+
const withMin = base.minLength(3);
|
|
98
|
+
|
|
99
|
+
// base no cambia
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3) Reglas transversales
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
- emptyAsNull: transforma string vacio a null antes de validar.
|
|
89
|
-
- defaultValue: valor por defecto para undefined y, en algunos casos, null.
|
|
90
|
-
- badTypeMessage: reemplaza el mensaje de tipo invalido.
|
|
104
|
+
Muchos validadores comparten estas opciones:
|
|
91
105
|
|
|
92
|
-
|
|
106
|
+
- `isRequired`: fuerza existencia del valor.
|
|
107
|
+
- `emptyAsNull`: transforma `""` a `null` antes de validar.
|
|
108
|
+
- `defaultValue`: valor por defecto para `undefined` y ciertos casos de `null`.
|
|
109
|
+
- `badTypeMessage`: reemplaza mensaje de tipo invalido.
|
|
93
110
|
|
|
94
|
-
|
|
111
|
+
### 4) Mensajes personalizados
|
|
95
112
|
|
|
96
|
-
|
|
97
|
-
- Funcion callback con el objeto de valores de la regla.
|
|
98
|
-
- Objeto con estructura val + message.
|
|
113
|
+
Puedes pasar mensajes como:
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
- `string` fijo.
|
|
116
|
+
- callback usando el valor de la regla.
|
|
117
|
+
- objeto `{ val, message }`.
|
|
101
118
|
|
|
102
119
|
```ts
|
|
103
120
|
const age = V.NumberNotNull().min(18, (v) => `Edad minima: ${v.min}`);
|
|
@@ -105,7 +122,13 @@ const age = V.NumberNotNull().min(18, (v) => `Edad minima: ${v.min}`);
|
|
|
105
122
|
|
|
106
123
|
## API publica
|
|
107
124
|
|
|
108
|
-
Import principal:
|
|
125
|
+
Import principal recomendado:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { Verifiers as V } from "structure-verifier";
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Import completo disponible:
|
|
109
132
|
|
|
110
133
|
```ts
|
|
111
134
|
import {
|
|
@@ -133,17 +156,17 @@ import {
|
|
|
133
156
|
} from "structure-verifier";
|
|
134
157
|
```
|
|
135
158
|
|
|
136
|
-
Tambien se exportan
|
|
159
|
+
Tambien se exportan estos tipos de condiciones:
|
|
137
160
|
|
|
138
|
-
- VAnyConditions
|
|
139
|
-
- VArrayConditions
|
|
140
|
-
- VBooleanConditions
|
|
141
|
-
- VDateConditions
|
|
142
|
-
- VNumberConditions
|
|
143
|
-
- VObjectConditions
|
|
144
|
-
- VObjectConditionsNotNull
|
|
145
|
-
- VStringConditions
|
|
146
|
-
- VUUIDConditions
|
|
161
|
+
- `VAnyConditions`
|
|
162
|
+
- `VArrayConditions`
|
|
163
|
+
- `VBooleanConditions`
|
|
164
|
+
- `VDateConditions`
|
|
165
|
+
- `VNumberConditions`
|
|
166
|
+
- `VObjectConditions`
|
|
167
|
+
- `VObjectConditionsNotNull`
|
|
168
|
+
- `VStringConditions`
|
|
169
|
+
- `VUUIDConditions`
|
|
147
170
|
|
|
148
171
|
## Estilos de uso
|
|
149
172
|
|
|
@@ -163,281 +186,186 @@ import { VStringNotNull } from "structure-verifier";
|
|
|
163
186
|
const nameV = new VStringNotNull({ minLength: 3 });
|
|
164
187
|
```
|
|
165
188
|
|
|
166
|
-
### Callable constructors
|
|
189
|
+
### Callable constructors en `Verifiers`
|
|
167
190
|
|
|
168
|
-
|
|
191
|
+
Los miembros de `Verifiers` aceptan llamada normal o `new`.
|
|
169
192
|
|
|
170
193
|
```ts
|
|
171
194
|
const a = V.NumberNotNull({ min: 1 });
|
|
172
195
|
const b = new V.NumberNotNull({ min: 1 });
|
|
173
196
|
```
|
|
174
197
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
### Number y NumberNotNull
|
|
178
|
-
|
|
179
|
-
Retorno:
|
|
180
|
-
|
|
181
|
-
- VNumber: number | null
|
|
182
|
-
- VNumberNotNull: number
|
|
183
|
-
|
|
184
|
-
Condiciones:
|
|
185
|
-
|
|
186
|
-
- min
|
|
187
|
-
- max
|
|
188
|
-
- in
|
|
189
|
-
- notIn
|
|
190
|
-
- maxDecimalPlaces
|
|
191
|
-
- minDecimalPlaces
|
|
192
|
-
- isRequired
|
|
193
|
-
- emptyAsNull
|
|
194
|
-
- defaultValue
|
|
195
|
-
- badTypeMessage
|
|
196
|
-
|
|
197
|
-
Comportamiento clave:
|
|
198
|
-
|
|
199
|
-
- Convierte el valor usando Number(data).
|
|
200
|
-
- Rechaza string vacio y NaN.
|
|
201
|
-
|
|
202
|
-
Ejemplo:
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
const priceV = V.NumberNotNull().min(0).maxDecimalPlaces(2);
|
|
206
|
-
const price = priceV.check("25.99");
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### String y StringNotNull
|
|
210
|
-
|
|
211
|
-
Retorno:
|
|
198
|
+
## Validadores disponibles
|
|
212
199
|
|
|
213
|
-
|
|
214
|
-
- VStringNotNull: string
|
|
200
|
+
### Number / NumberNotNull
|
|
215
201
|
|
|
216
|
-
|
|
202
|
+
Salida:
|
|
217
203
|
|
|
218
|
-
-
|
|
219
|
-
-
|
|
220
|
-
- regex
|
|
221
|
-
- notRegex
|
|
222
|
-
- in
|
|
223
|
-
- notIn
|
|
224
|
-
- strictMode
|
|
225
|
-
- ignoreCase
|
|
226
|
-
- isRequired
|
|
227
|
-
- emptyAsNull
|
|
228
|
-
- defaultValue
|
|
229
|
-
- badTypeMessage
|
|
204
|
+
- `VNumber`: `number | null`
|
|
205
|
+
- `VNumberNotNull`: `number`
|
|
230
206
|
|
|
231
|
-
|
|
207
|
+
Reglas:
|
|
232
208
|
|
|
233
|
-
-
|
|
234
|
-
-
|
|
235
|
-
-
|
|
209
|
+
- `min`
|
|
210
|
+
- `max`
|
|
211
|
+
- `in`
|
|
212
|
+
- `notIn`
|
|
213
|
+
- `maxDecimalPlaces`
|
|
214
|
+
- `minDecimalPlaces`
|
|
215
|
+
- reglas transversales (`isRequired`, `emptyAsNull`, `defaultValue`, `badTypeMessage`)
|
|
236
216
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
```ts
|
|
240
|
-
const roleV = V.StringNotNull()
|
|
241
|
-
.ignoreCase()
|
|
242
|
-
.in(["admin", "user", "guest"])
|
|
243
|
-
.trim()
|
|
244
|
-
.toLowerCase();
|
|
217
|
+
Comportamiento importante:
|
|
245
218
|
|
|
246
|
-
|
|
247
|
-
|
|
219
|
+
- Convierte con `Number(data)`.
|
|
220
|
+
- Rechaza `""` y valores `NaN`.
|
|
248
221
|
|
|
249
|
-
###
|
|
222
|
+
### String / StringNotNull
|
|
250
223
|
|
|
251
|
-
|
|
224
|
+
Salida:
|
|
252
225
|
|
|
253
|
-
-
|
|
254
|
-
-
|
|
226
|
+
- `VString`: `string | null`
|
|
227
|
+
- `VStringNotNull`: `string`
|
|
255
228
|
|
|
256
|
-
|
|
229
|
+
Reglas:
|
|
257
230
|
|
|
258
|
-
-
|
|
259
|
-
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
262
|
-
-
|
|
231
|
+
- `minLength`
|
|
232
|
+
- `maxLength`
|
|
233
|
+
- `regex`
|
|
234
|
+
- `notRegex`
|
|
235
|
+
- `in`
|
|
236
|
+
- `notIn`
|
|
237
|
+
- `strictMode`
|
|
238
|
+
- `ignoreCase`
|
|
239
|
+
- reglas transversales
|
|
263
240
|
|
|
264
|
-
Comportamiento
|
|
241
|
+
Comportamiento importante:
|
|
265
242
|
|
|
266
|
-
- En modo normal
|
|
267
|
-
- En strictMode
|
|
243
|
+
- En modo normal convierte con `String(data)`.
|
|
244
|
+
- En `strictMode` exige tipo string real.
|
|
245
|
+
- `ignoreCase` aplica a reglas `in` y `notIn`.
|
|
268
246
|
|
|
269
|
-
|
|
247
|
+
### Boolean / BooleanNotNull
|
|
270
248
|
|
|
271
|
-
|
|
272
|
-
const active = V.BooleanNotNull().check("true");
|
|
273
|
-
const strictActive = V.BooleanNotNull().strictMode().check(true);
|
|
274
|
-
```
|
|
249
|
+
Salida:
|
|
275
250
|
|
|
276
|
-
|
|
251
|
+
- `VBoolean`: `boolean | null`
|
|
252
|
+
- `VBooleanNotNull`: `boolean`
|
|
277
253
|
|
|
278
|
-
|
|
254
|
+
Reglas:
|
|
279
255
|
|
|
280
|
-
-
|
|
281
|
-
-
|
|
256
|
+
- `strictMode`
|
|
257
|
+
- reglas transversales
|
|
282
258
|
|
|
283
|
-
|
|
259
|
+
Comportamiento importante:
|
|
284
260
|
|
|
285
|
-
-
|
|
286
|
-
-
|
|
287
|
-
- strictMode
|
|
288
|
-
- isRequired
|
|
289
|
-
- emptyAsNull
|
|
290
|
-
- defaultValue
|
|
291
|
-
- badTypeMessage
|
|
261
|
+
- Modo normal acepta: `true`, `false`, `1`, `0`, `"1"`, `"0"`, `"true"`, `"false"`.
|
|
262
|
+
- `strictMode` acepta solo boolean real.
|
|
292
263
|
|
|
293
|
-
|
|
264
|
+
### UUID / UUIDNotNull
|
|
294
265
|
|
|
295
|
-
|
|
296
|
-
- Si allowNoHyphens no esta activo, exige formato 8-4-4-4-12.
|
|
266
|
+
Salida:
|
|
297
267
|
|
|
298
|
-
|
|
268
|
+
- `VUUID`: `string | null`
|
|
269
|
+
- `VUUIDNotNull`: `string`
|
|
299
270
|
|
|
300
|
-
|
|
301
|
-
const uuidV = V.UUIDNotNull().version(4);
|
|
302
|
-
const id = uuidV.check("550E8400E29B41D4A716446655440000");
|
|
303
|
-
```
|
|
271
|
+
Reglas:
|
|
304
272
|
|
|
305
|
-
|
|
273
|
+
- `version` (`1 | 2 | 3 | 4 | 5`)
|
|
274
|
+
- `allowNoHyphens`
|
|
275
|
+
- `strictMode`
|
|
276
|
+
- reglas transversales
|
|
306
277
|
|
|
307
|
-
|
|
278
|
+
Comportamiento importante:
|
|
308
279
|
|
|
309
|
-
-
|
|
310
|
-
-
|
|
280
|
+
- Normaliza salida a minusculas con formato `8-4-4-4-12`.
|
|
281
|
+
- Si `allowNoHyphens` es `false`, exige UUID con guiones.
|
|
311
282
|
|
|
312
|
-
|
|
283
|
+
### Date / DateNotNull
|
|
313
284
|
|
|
314
|
-
|
|
315
|
-
- timeZone
|
|
316
|
-
- maxDate
|
|
317
|
-
- minDate
|
|
318
|
-
- isRequired
|
|
319
|
-
- emptyAsNull
|
|
320
|
-
- defaultValue
|
|
321
|
-
- badTypeMessage
|
|
285
|
+
Salida:
|
|
322
286
|
|
|
323
|
-
|
|
287
|
+
- `VDate`: `datetime.Dayjs | null`
|
|
288
|
+
- `VDateNotNull`: `datetime.Dayjs`
|
|
324
289
|
|
|
325
|
-
|
|
326
|
-
- Si no defines timeZone usa UTC por defecto.
|
|
327
|
-
- Si format no incluye zona horaria, se aplica la zona configurada.
|
|
290
|
+
Reglas:
|
|
328
291
|
|
|
329
|
-
|
|
292
|
+
- `format`
|
|
293
|
+
- `timeZone`
|
|
294
|
+
- `maxDate`
|
|
295
|
+
- `minDate`
|
|
296
|
+
- reglas transversales
|
|
330
297
|
|
|
331
|
-
|
|
332
|
-
import { Verifiers as V, datetime } from "structure-verifier";
|
|
298
|
+
Comportamiento importante:
|
|
333
299
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
.minDate(datetime("2024-01-01"));
|
|
300
|
+
- Soporta entrada `number`, `string`, `Date` y `datetime.Dayjs`.
|
|
301
|
+
- Si no defines `timeZone`, usa `UTC`.
|
|
302
|
+
- Si el `format` no incluye zona horaria, aplica la zona configurada.
|
|
338
303
|
|
|
339
|
-
|
|
340
|
-
```
|
|
304
|
+
### Array / ArrayNotNull
|
|
341
305
|
|
|
342
|
-
|
|
306
|
+
Salida:
|
|
343
307
|
|
|
344
|
-
|
|
308
|
+
- `VArray`: `ReturnType<T["check"]>[] | null`
|
|
309
|
+
- `VArrayNotNull`: `ReturnType<T["check"]>[]`
|
|
345
310
|
|
|
346
|
-
|
|
347
|
-
const tagsV = V.Array(V.StringNotNull(), { minLength: 1 });
|
|
348
|
-
const tagsRequiredV = V.ArrayNotNull(V.StringNotNull(), { minLength: 1 });
|
|
349
|
-
```
|
|
311
|
+
Reglas:
|
|
350
312
|
|
|
351
|
-
|
|
313
|
+
- `minLength`
|
|
314
|
+
- `maxLength`
|
|
315
|
+
- reglas transversales
|
|
352
316
|
|
|
353
|
-
|
|
354
|
-
- VArrayNotNull: ReturnType<T["check"]>[]
|
|
355
|
-
|
|
356
|
-
Condiciones:
|
|
357
|
-
|
|
358
|
-
- minLength
|
|
359
|
-
- maxLength
|
|
360
|
-
- isRequired
|
|
361
|
-
- emptyAsNull
|
|
362
|
-
- defaultValue
|
|
363
|
-
- badTypeMessage
|
|
364
|
-
|
|
365
|
-
Comportamiento clave:
|
|
317
|
+
Comportamiento importante:
|
|
366
318
|
|
|
367
319
|
- Valida item por item con el verificador interno.
|
|
368
|
-
- En errores anidados agrega rutas como [0]
|
|
369
|
-
|
|
370
|
-
### Object y ObjectNotNull
|
|
320
|
+
- En errores anidados agrega rutas como `[0]`, `[1].name`, etc.
|
|
371
321
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
```ts
|
|
375
|
-
const userV = V.Object(
|
|
376
|
-
{
|
|
377
|
-
name: V.StringNotNull(),
|
|
378
|
-
age: V.Number(),
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
strictMode: true,
|
|
382
|
-
ignoreCase: false,
|
|
383
|
-
takeAllValues: false,
|
|
384
|
-
},
|
|
385
|
-
);
|
|
386
|
-
```
|
|
322
|
+
### Object / ObjectNotNull
|
|
387
323
|
|
|
388
|
-
|
|
324
|
+
Salida:
|
|
389
325
|
|
|
390
|
-
- VObject
|
|
391
|
-
- VObjectNotNull
|
|
326
|
+
- `VObject`: objeto tipado o `null`
|
|
327
|
+
- `VObjectNotNull`: objeto tipado
|
|
392
328
|
|
|
393
|
-
|
|
329
|
+
Reglas:
|
|
394
330
|
|
|
395
|
-
- invalidPropertyMessage
|
|
396
|
-
- strictMode
|
|
397
|
-
- ignoreCase
|
|
398
|
-
- takeAllValues
|
|
399
|
-
- conds
|
|
400
|
-
-
|
|
401
|
-
- emptyAsNull
|
|
402
|
-
- defaultValue
|
|
403
|
-
- badTypeMessage
|
|
331
|
+
- `invalidPropertyMessage`
|
|
332
|
+
- `strictMode`
|
|
333
|
+
- `ignoreCase`
|
|
334
|
+
- `takeAllValues`
|
|
335
|
+
- `conds`
|
|
336
|
+
- reglas transversales
|
|
404
337
|
|
|
405
|
-
Comportamiento
|
|
338
|
+
Comportamiento importante:
|
|
406
339
|
|
|
407
|
-
- strictMode rechaza propiedades no declaradas.
|
|
408
|
-
- ignoreCase permite mapear llaves sin distinguir mayusculas.
|
|
409
|
-
- takeAllValues conserva propiedades extra en la salida.
|
|
410
|
-
- conds ejecuta
|
|
340
|
+
- `strictMode`: rechaza propiedades no declaradas.
|
|
341
|
+
- `ignoreCase`: permite mapear llaves sin distinguir mayusculas/minusculas.
|
|
342
|
+
- `takeAllValues`: conserva propiedades extra en la salida.
|
|
343
|
+
- `conds`: ejecuta validacion de negocio final sobre el objeto ya validado.
|
|
411
344
|
|
|
412
345
|
### Any
|
|
413
346
|
|
|
414
|
-
|
|
347
|
+
Salida:
|
|
415
348
|
|
|
416
|
-
- VAny
|
|
349
|
+
- `VAny`: `any | null`
|
|
417
350
|
|
|
418
|
-
|
|
351
|
+
Reglas:
|
|
419
352
|
|
|
420
|
-
-
|
|
421
|
-
- emptyAsNull
|
|
422
|
-
- defaultValue
|
|
423
|
-
- badTypeMessage
|
|
353
|
+
- reglas transversales
|
|
424
354
|
|
|
425
|
-
## Transformaciones
|
|
355
|
+
## Transformaciones
|
|
426
356
|
|
|
427
|
-
La clase base Verifier incluye transform(mapper)
|
|
357
|
+
La clase base `Verifier` incluye `transform(mapper)` para postprocesar salida validada.
|
|
428
358
|
|
|
429
|
-
|
|
359
|
+
`VString` y `VStringNotNull` incluyen helpers:
|
|
430
360
|
|
|
431
|
-
- trim
|
|
432
|
-
- trimStart
|
|
433
|
-
- trimEnd
|
|
434
|
-
- toLowerCase
|
|
435
|
-
- toUpperCase
|
|
436
|
-
- removeAccents
|
|
437
|
-
- padStart
|
|
438
|
-
- padEnd
|
|
439
|
-
|
|
440
|
-
Ejemplo:
|
|
361
|
+
- `trim`
|
|
362
|
+
- `trimStart`
|
|
363
|
+
- `trimEnd`
|
|
364
|
+
- `toLowerCase`
|
|
365
|
+
- `toUpperCase`
|
|
366
|
+
- `removeAccents`
|
|
367
|
+
- `padStart`
|
|
368
|
+
- `padEnd`
|
|
441
369
|
|
|
442
370
|
```ts
|
|
443
371
|
const usernameV = V.StringNotNull({ minLength: 3 })
|
|
@@ -475,39 +403,53 @@ type NumberRequired = InferFactoryType<typeof V.NumberNotNull>;
|
|
|
475
403
|
|
|
476
404
|
## Manejo de errores
|
|
477
405
|
|
|
478
|
-
Cuando una validacion falla se lanza VerificationError
|
|
406
|
+
Cuando una validacion falla se lanza `VerificationError`.
|
|
479
407
|
|
|
480
|
-
|
|
408
|
+
Campos principales:
|
|
481
409
|
|
|
482
|
-
- message
|
|
483
|
-
- errors
|
|
484
|
-
- errorsObj
|
|
410
|
+
- `message`: string unico con errores concatenados por `;`.
|
|
411
|
+
- `errors`: arreglo de mensajes planos.
|
|
412
|
+
- `errorsObj`: arreglo con `key`, `message` y metadatos.
|
|
485
413
|
|
|
486
414
|
Ejemplo:
|
|
487
415
|
|
|
488
416
|
```ts
|
|
417
|
+
import { Verifiers as V, VerificationError } from "structure-verifier";
|
|
418
|
+
|
|
489
419
|
try {
|
|
490
|
-
V.ObjectNotNull(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
420
|
+
V.ObjectNotNull(
|
|
421
|
+
{
|
|
422
|
+
name: V.StringNotNull({ minLength: 3 }),
|
|
423
|
+
tags: V.ArrayNotNull(V.StringNotNull(), { minLength: 1 }),
|
|
424
|
+
},
|
|
425
|
+
{ strictMode: true },
|
|
426
|
+
).check({ name: "Al", tags: [], extra: true });
|
|
494
427
|
} catch (error) {
|
|
495
428
|
if (error instanceof VerificationError) {
|
|
429
|
+
console.log(error.message);
|
|
496
430
|
console.log(error.errors);
|
|
497
431
|
console.log(error.errorsObj);
|
|
498
432
|
}
|
|
499
433
|
}
|
|
500
434
|
```
|
|
501
435
|
|
|
502
|
-
|
|
436
|
+
Posible salida en `errorsObj`:
|
|
503
437
|
|
|
504
|
-
|
|
438
|
+
```ts
|
|
439
|
+
[
|
|
440
|
+
{ key: "name", message: "debe tener una longitud minima de 3" },
|
|
441
|
+
{ key: "tags", message: "debe tener al menos 1 elementos" },
|
|
442
|
+
{ key: "extra", message: "no es una propiedad valida" },
|
|
443
|
+
];
|
|
444
|
+
```
|
|
505
445
|
|
|
506
|
-
|
|
507
|
-
- timezone
|
|
508
|
-
- customParseFormat
|
|
446
|
+
## datetime (dayjs)
|
|
509
447
|
|
|
510
|
-
|
|
448
|
+
La libreria exporta `dayjs` como `datetime` con plugins habilitados:
|
|
449
|
+
|
|
450
|
+
- `utc`
|
|
451
|
+
- `timezone`
|
|
452
|
+
- `customParseFormat`
|
|
511
453
|
|
|
512
454
|
```ts
|
|
513
455
|
import { datetime } from "structure-verifier";
|
|
@@ -517,53 +459,14 @@ const utc = now.tz("UTC").format();
|
|
|
517
459
|
console.log(utc);
|
|
518
460
|
```
|
|
519
461
|
|
|
520
|
-
##
|
|
521
|
-
|
|
522
|
-
### Validacion de payload API
|
|
523
|
-
|
|
524
|
-
```ts
|
|
525
|
-
const createOrderV = V.ObjectNotNull(
|
|
526
|
-
{
|
|
527
|
-
customerId: V.UUIDNotNull({ version: 4 }),
|
|
528
|
-
items: V.ArrayNotNull(
|
|
529
|
-
V.ObjectNotNull({
|
|
530
|
-
sku: V.StringNotNull({ minLength: 1 }),
|
|
531
|
-
quantity: V.NumberNotNull({ min: 1 }),
|
|
532
|
-
}),
|
|
533
|
-
{ minLength: 1 },
|
|
534
|
-
),
|
|
535
|
-
createdAt: V.DateNotNull().timeZone("UTC"),
|
|
536
|
-
},
|
|
537
|
-
{
|
|
538
|
-
strictMode: true,
|
|
539
|
-
},
|
|
540
|
-
);
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
### conds para reglas de negocio
|
|
462
|
+
## Buenas practicas para v1.0.0
|
|
544
463
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
{
|
|
552
|
-
conds: (value) => {
|
|
553
|
-
if (value.age < 18 && value.hasParentalConsent !== true) {
|
|
554
|
-
throw new Error("Parental consent is required for minors");
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
|
-
},
|
|
558
|
-
);
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
## Scripts de desarrollo
|
|
562
|
-
|
|
563
|
-
```bash
|
|
564
|
-
npm test
|
|
565
|
-
npm run dev
|
|
566
|
-
```
|
|
464
|
+
- Define siempre `strictMode: true` en payloads de entrada externa.
|
|
465
|
+
- Usa variantes `NotNull` en campos de negocio obligatorios.
|
|
466
|
+
- Agrega reglas semanticas con `conds` para validaciones cruzadas.
|
|
467
|
+
- Encadena normalizaciones (`trim`, `toLowerCase`, etc.) para salida consistente.
|
|
468
|
+
- Centraliza mensajes custom cuando quieras UX de errores uniforme.
|
|
469
|
+
- Cubre cada esquema critico con pruebas de casos validos e invalidos.
|
|
567
470
|
|
|
568
471
|
## Licencia
|
|
569
472
|
|