structure-verifier 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +335 -161
  2. package/dist/index.d.ts +8 -16
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/error/v_error.js +4 -3
  5. package/dist/src/error/v_error.js.map +1 -1
  6. package/dist/src/verifiers/any/v_any.js +0 -1
  7. package/dist/src/verifiers/any/v_any.js.map +1 -1
  8. package/dist/src/verifiers/array/v_array.d.ts +21 -3
  9. package/dist/src/verifiers/array/v_array.js +24 -5
  10. package/dist/src/verifiers/array/v_array.js.map +1 -1
  11. package/dist/src/verifiers/boolean/v_boolean.d.ts +4 -0
  12. package/dist/src/verifiers/boolean/v_boolean.js +15 -5
  13. package/dist/src/verifiers/boolean/v_boolean.js.map +1 -1
  14. package/dist/src/verifiers/date/v_date.d.ts +26 -0
  15. package/dist/src/verifiers/date/v_date.js +28 -1
  16. package/dist/src/verifiers/date/v_date.js.map +1 -1
  17. package/dist/src/verifiers/helpers/conditionMessage.d.ts +3 -0
  18. package/dist/src/verifiers/helpers/conditionMessage.js +19 -0
  19. package/dist/src/verifiers/helpers/conditionMessage.js.map +1 -0
  20. package/dist/src/verifiers/number/v_number.d.ts +38 -0
  21. package/dist/src/verifiers/number/v_number.js +40 -1
  22. package/dist/src/verifiers/number/v_number.js.map +1 -1
  23. package/dist/src/verifiers/object/v_object.d.ts +7 -0
  24. package/dist/src/verifiers/object/v_object.js +21 -0
  25. package/dist/src/verifiers/object/v_object.js.map +1 -1
  26. package/dist/src/verifiers/string/v_string.d.ts +58 -0
  27. package/dist/src/verifiers/string/v_string.js +109 -11
  28. package/dist/src/verifiers/string/v_string.js.map +1 -1
  29. package/dist/src/verifiers/uuid/v_uuid.d.ts +8 -0
  30. package/dist/src/verifiers/uuid/v_uuid.js +35 -4
  31. package/dist/src/verifiers/uuid/v_uuid.js.map +1 -1
  32. package/dist/src/verifiers/verifier.d.ts +1 -0
  33. package/dist/src/verifiers/verifier.js +8 -0
  34. package/dist/src/verifiers/verifier.js.map +1 -1
  35. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,33 @@
1
- # structure-verifier 0.0.16
1
+ # structure-verifier
2
2
 
3
- Libreria TypeScript para validar estructuras de datos con tipado inferido.
3
+ Libreria de validacion para TypeScript orientada a esquemas declarativos, tipado inferido y errores detallados por ruta.
4
4
 
5
- Permite validar valores simples y estructuras anidadas (objetos y arrays), con errores detallados por ruta (por ejemplo: name, items[0], address.city).
5
+ Ideal para validar payloads de API, formularios, configuraciones y estructuras anidadas complejas.
6
+
7
+ Version actual: 0.0.17
8
+
9
+ ## Contenido
10
+
11
+ - Caracteristicas
12
+ - Instalacion
13
+ - Inicio rapido
14
+ - Conceptos base
15
+ - API publica
16
+ - Referencia completa de validadores
17
+ - Transformaciones de valores
18
+ - Tipado inferido
19
+ - Manejo de errores
20
+ - Ejemplos avanzados
21
+ - Scripts de desarrollo
22
+
23
+ ## Caracteristicas
24
+
25
+ - Validadores para number, string, boolean, uuid, date, array, object y any.
26
+ - Soporte para estructuras anidadas con errores por ruta.
27
+ - API fluida por clases y API de fabrica mediante Verifiers.
28
+ - Tipado inferido en compile-time para mantener consistencia del dominio.
29
+ - Personalizacion de mensajes por regla y por validador.
30
+ - Integracion con dayjs (exportado como datetime) para manejo de fechas.
6
31
 
7
32
  ## Instalacion
8
33
 
@@ -15,31 +40,69 @@ npm install structure-verifier
15
40
  ```ts
16
41
  import { Verifiers as V, VerificationError } from "structure-verifier";
17
42
 
18
- const userValidator = V.ObjectNotNull({
19
- id: V.UUIDNotNull({ version: 4 }),
20
- name: V.StringNotNull({ minLength: 2 }),
21
- age: V.Number({ min: 0 }),
22
- active: V.BooleanNotNull(),
23
- });
43
+ const userVerifier = V.ObjectNotNull(
44
+ {
45
+ id: V.UUIDNotNull({ version: 4 }),
46
+ name: V.StringNotNull({ minLength: 2 }),
47
+ age: V.Number({ min: 0 }),
48
+ active: V.BooleanNotNull(),
49
+ tags: V.ArrayNotNull(V.StringNotNull()).minLength(1),
50
+ },
51
+ {
52
+ strictMode: true,
53
+ },
54
+ );
24
55
 
25
56
  try {
26
- const user = userValidator.check({
57
+ const user = userVerifier.check({
27
58
  id: "550e8400-e29b-41d4-a716-446655440000",
28
59
  name: "Ana",
29
- age: 31,
60
+ age: "31",
30
61
  active: "true",
62
+ tags: ["admin"],
31
63
  });
32
64
 
33
- // user queda tipado con los tipos inferidos de cada propiedad
34
65
  console.log(user);
35
66
  } catch (error) {
36
67
  if (error instanceof VerificationError) {
37
- console.log(error.errors); // mensajes planos
38
- console.log(error.errorsObj); // mensajes con key y metadatos
68
+ console.log(error.message);
69
+ console.log(error.errors);
70
+ console.log(error.errorsObj);
39
71
  }
40
72
  }
41
73
  ```
42
74
 
75
+ ## Conceptos base
76
+
77
+ ### 1) Nullable vs NotNull
78
+
79
+ - VNumber, VString, VBoolean, VDate, VUUID, VArray y VObject retornan tipo nullable.
80
+ - Sus versiones NotNull retornan el tipo requerido.
81
+ - Tambien puedes promover un validador nullable a requerido con required().
82
+
83
+ ### 2) Reglas comunes
84
+
85
+ Muchos validadores comparten estas opciones:
86
+
87
+ - isRequired: fuerza que el valor exista.
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.
91
+
92
+ ### 3) Mensajes personalizados
93
+
94
+ Las reglas aceptan mensajes de estas formas:
95
+
96
+ - String fijo.
97
+ - Funcion callback con el objeto de valores de la regla.
98
+ - Objeto con estructura val + message.
99
+
100
+ Ejemplo:
101
+
102
+ ```ts
103
+ const age = V.NumberNotNull().min(18, (v) => `Edad minima: ${v.min}`);
104
+ ```
105
+
43
106
  ## API publica
44
107
 
45
108
  Import principal:
@@ -52,116 +115,71 @@ import {
52
115
  InferType,
53
116
  InferFactoryType,
54
117
  VAny,
55
- VAnyConditions,
56
118
  VArray,
57
119
  VArrayNotNull,
58
- VArrayConditions,
59
120
  VBoolean,
60
121
  VBooleanNotNull,
61
- VBooleanConditions,
62
122
  VDate,
63
123
  VDateNotNull,
64
- VDateConditions,
65
124
  VNumber,
66
125
  VNumberNotNull,
67
- VNumberConditions,
68
126
  VObject,
69
127
  VObjectNotNull,
70
- VObjectConditions,
71
- VObjectConditionsNotNull,
72
128
  VString,
73
129
  VStringNotNull,
74
- VStringConditions,
75
130
  VUUID,
76
131
  VUUIDNotNull,
77
- VUUIDConditions,
78
132
  datetime,
79
133
  } from "structure-verifier";
80
134
  ```
81
135
 
82
- ## Formas de uso
136
+ Tambien se exportan los tipos de condiciones:
83
137
 
84
- La libreria soporta dos estilos:
138
+ - VAnyConditions
139
+ - VArrayConditions
140
+ - VBooleanConditions
141
+ - VDateConditions
142
+ - VNumberConditions
143
+ - VObjectConditions
144
+ - VObjectConditionsNotNull
145
+ - VStringConditions
146
+ - VUUIDConditions
85
147
 
86
- 1. API recomendada con Verifiers (callable, con o sin new)
87
- 2. Clases directas (new VString(...), new VObject(...), etc.)
148
+ ## Estilos de uso
88
149
 
89
- Ejemplo con Verifiers:
150
+ ### API de fabrica (recomendada)
90
151
 
91
152
  ```ts
92
153
  import { Verifiers as V } from "structure-verifier";
93
154
 
94
- const a = V.StringNotNull({ minLength: 3 });
95
- const b = new V.StringNotNull({ minLength: 3 });
96
-
97
- console.log(a.check("hola"));
98
- console.log(b.check("hola"));
155
+ const nameV = V.StringNotNull({ minLength: 3 });
99
156
  ```
100
157
 
101
- ## Inferencia de tipos
102
-
103
- ### InferType
158
+ ### Clases directas
104
159
 
105
160
  ```ts
106
- import { InferType, Verifiers as V } from "structure-verifier";
107
-
108
- const v = V.ObjectNotNull({
109
- id: V.UUIDNotNull(),
110
- tags: V.ArrayNotNull(V.StringNotNull()),
111
- });
161
+ import { VStringNotNull } from "structure-verifier";
112
162
 
113
- type User = InferType<typeof v>;
163
+ const nameV = new VStringNotNull({ minLength: 3 });
114
164
  ```
115
165
 
116
- ### InferFactoryType
166
+ ### Callable constructors
117
167
 
118
- Funciona con funciones que retornan un Verifier (por ejemplo, miembros callable de Verifiers).
168
+ En Verifiers puedes usar los miembros como funcion o con new.
119
169
 
120
170
  ```ts
121
- import { InferFactoryType, Verifiers as V } from "structure-verifier";
122
-
123
- type NullableNumber = InferFactoryType<typeof V.Number>; // number | null
124
- type RequiredNumber = InferFactoryType<typeof V.NumberNotNull>; // number
171
+ const a = V.NumberNotNull({ min: 1 });
172
+ const b = new V.NumberNotNull({ min: 1 });
125
173
  ```
126
174
 
127
- ## Manejo de errores
175
+ ## Referencia completa de validadores
128
176
 
129
- Cuando una validacion falla se lanza VerificationError.
177
+ ### Number y NumberNotNull
130
178
 
131
- ```ts
132
- try {
133
- V.NumberNotNull({ min: 10 }).check(5);
134
- } catch (error) {
135
- if (error instanceof VerificationError) {
136
- console.log(error.errors); // ["debe ser mayor o igual a 10"]
137
- console.log(error.errorsObj); // [{ key: "", message: "..." }]
138
- }
139
- }
140
- ```
141
-
142
- ## Opciones comunes
143
-
144
- Muchos validadores comparten estas opciones:
145
-
146
- - isRequired: fuerza que el valor exista.
147
- - emptyAsNull: si llega string vacio, se convierte a null antes de validar.
148
- - defaultValue: valor por defecto si llega undefined (y en algunos flujos tambien null).
149
- - badTypeMessage: mensaje personalizado de tipo invalido.
179
+ Retorno:
150
180
 
151
- Puedes pasar mensajes simples o mensajes dinamicos con estructura:
152
-
153
- ```ts
154
- { val: valorReal, message: (values) => "mensaje" }
155
- ```
156
-
157
- ## Validadores
158
-
159
- ### Number / NumberNotNull
160
-
161
- ```ts
162
- const n1 = V.Number();
163
- const n2 = V.NumberNotNull();
164
- ```
181
+ - VNumber: number | null
182
+ - VNumberNotNull: number
165
183
 
166
184
  Condiciones:
167
185
 
@@ -176,18 +194,25 @@ Condiciones:
176
194
  - defaultValue
177
195
  - badTypeMessage
178
196
 
179
- Notas:
197
+ Comportamiento clave:
180
198
 
181
- - Convierte con Number(data), por lo que acepta strings numericos como "42".
182
- - "" y NaN fallan.
199
+ - Convierte el valor usando Number(data).
200
+ - Rechaza string vacio y NaN.
183
201
 
184
- ### String / StringNotNull
202
+ Ejemplo:
185
203
 
186
204
  ```ts
187
- const s1 = V.String();
188
- const s2 = V.StringNotNull();
205
+ const priceV = V.NumberNotNull().min(0).maxDecimalPlaces(2);
206
+ const price = priceV.check("25.99");
189
207
  ```
190
208
 
209
+ ### String y StringNotNull
210
+
211
+ Retorno:
212
+
213
+ - VString: string | null
214
+ - VStringNotNull: string
215
+
191
216
  Condiciones:
192
217
 
193
218
  - minLength
@@ -203,19 +228,31 @@ Condiciones:
203
228
  - defaultValue
204
229
  - badTypeMessage
205
230
 
206
- Notas:
231
+ Comportamiento clave:
207
232
 
208
- - En modo no estricto convierte con String(data).
209
- - En strictMode exige typeof data === "string".
233
+ - En modo normal convierte con String(data).
234
+ - En strictMode exige string real.
210
235
  - ignoreCase afecta in y notIn.
211
236
 
212
- ### Boolean / BooleanNotNull
237
+ Ejemplo:
213
238
 
214
239
  ```ts
215
- const b1 = V.Boolean();
216
- const b2 = V.BooleanNotNull();
240
+ const roleV = V.StringNotNull()
241
+ .ignoreCase()
242
+ .in(["admin", "user", "guest"])
243
+ .trim()
244
+ .toLowerCase();
245
+
246
+ const role = roleV.check(" ADMIN ");
217
247
  ```
218
248
 
249
+ ### Boolean y BooleanNotNull
250
+
251
+ Retorno:
252
+
253
+ - VBoolean: boolean | null
254
+ - VBooleanNotNull: boolean
255
+
219
256
  Condiciones:
220
257
 
221
258
  - strictMode
@@ -224,18 +261,25 @@ Condiciones:
224
261
  - defaultValue
225
262
  - badTypeMessage
226
263
 
227
- Notas:
264
+ Comportamiento clave:
228
265
 
229
- - En modo no estricto acepta: true, false, 1, 0, "1", "0", "true", "false" (case-insensitive).
230
- - En strictMode solo acepta boolean real.
266
+ - En modo normal acepta: true, false, 1, 0, "1", "0", "true", "false".
267
+ - En strictMode solo acepta boolean.
231
268
 
232
- ### UUID / UUIDNotNull
269
+ Ejemplo:
233
270
 
234
271
  ```ts
235
- const u1 = V.UUID();
236
- const u2 = V.UUIDNotNull();
272
+ const active = V.BooleanNotNull().check("true");
273
+ const strictActive = V.BooleanNotNull().strictMode().check(true);
237
274
  ```
238
275
 
276
+ ### UUID y UUIDNotNull
277
+
278
+ Retorno:
279
+
280
+ - VUUID: string | null
281
+ - VUUIDNotNull: string
282
+
239
283
  Condiciones:
240
284
 
241
285
  - version (1 | 2 | 3 | 4 | 5)
@@ -246,73 +290,68 @@ Condiciones:
246
290
  - defaultValue
247
291
  - badTypeMessage
248
292
 
249
- Notas:
293
+ Comportamiento clave:
250
294
 
251
- - Devuelve UUID normalizado en minusculas y con guiones.
252
- - Si allowNoHyphens es false, exige formato 8-4-4-4-12.
295
+ - Normaliza salida a minusculas y formato con guiones.
296
+ - Si allowNoHyphens no esta activo, exige formato 8-4-4-4-12.
253
297
 
254
- ### Date / DateNotNull
298
+ Ejemplo:
255
299
 
256
300
  ```ts
257
- import { Verifiers as V, datetime } from "structure-verifier";
258
-
259
- const d1 = V.Date();
260
- const d2 = V.DateNotNull({
261
- format: "YYYY-MM-DD",
262
- timeZone: "UTC",
263
- minDate: datetime("2024-01-01"),
264
- maxDate: datetime("2026-12-31"),
265
- });
301
+ const uuidV = V.UUIDNotNull().version(4);
302
+ const id = uuidV.check("550E8400E29B41D4A716446655440000");
266
303
  ```
267
304
 
305
+ ### Date y DateNotNull
306
+
307
+ Retorno:
308
+
309
+ - VDate: datetime.Dayjs | null
310
+ - VDateNotNull: datetime.Dayjs
311
+
268
312
  Condiciones:
269
313
 
270
314
  - format
271
315
  - timeZone
272
- - minDate
273
316
  - maxDate
274
- - default
317
+ - minDate
275
318
  - isRequired
276
319
  - emptyAsNull
277
320
  - defaultValue
278
321
  - badTypeMessage
279
322
 
280
- Notas:
323
+ Comportamiento clave:
281
324
 
282
- - Retorna instancias dayjs (re-exportado como datetime).
283
- - Inputs soportados: number, string, Date y datetime.Dayjs.
284
- - timeZone por defecto: UTC.
325
+ - Entradas soportadas: number, string, Date y datetime.Dayjs.
326
+ - Si no defines timeZone usa UTC por defecto.
327
+ - Si format no incluye zona horaria, se aplica la zona configurada.
285
328
 
286
- ### Any
329
+ Ejemplo:
287
330
 
288
331
  ```ts
289
- const anyVal = V.Any();
290
- ```
332
+ import { Verifiers as V, datetime } from "structure-verifier";
291
333
 
292
- Condiciones:
334
+ const dateV = V.DateNotNull()
335
+ .format("YYYY-MM-DD")
336
+ .timeZone("America/Mexico_City")
337
+ .minDate(datetime("2024-01-01"));
293
338
 
294
- - isRequired
295
- - emptyAsNull
296
- - defaultValue
297
- - badTypeMessage
339
+ const d = dateV.check("2025-05-10");
340
+ ```
298
341
 
299
- ### Array / ArrayNotNull
342
+ ### Array y ArrayNotNull
300
343
 
301
344
  Firma:
302
345
 
303
346
  ```ts
304
- const arr1 = V.Array(verifier, conditions?);
305
- const arr2 = V.ArrayNotNull(verifier, conditions?);
347
+ const tagsV = V.Array(V.StringNotNull(), { minLength: 1 });
348
+ const tagsRequiredV = V.ArrayNotNull(V.StringNotNull(), { minLength: 1 });
306
349
  ```
307
350
 
308
- Ejemplo:
351
+ Retorno:
309
352
 
310
- ```ts
311
- const numbers = V.ArrayNotNull(V.NumberNotNull(), {
312
- minLength: 1,
313
- maxLength: 5,
314
- });
315
- ```
353
+ - VArray: ReturnType<T["check"]>[] | null
354
+ - VArrayNotNull: ReturnType<T["check"]>[]
316
355
 
317
356
  Condiciones:
318
357
 
@@ -323,36 +362,34 @@ Condiciones:
323
362
  - defaultValue
324
363
  - badTypeMessage
325
364
 
326
- Notas:
365
+ Comportamiento clave:
327
366
 
328
367
  - Valida item por item con el verificador interno.
329
- - En errores anidados utiliza claves como [0], [1].name, etc.
368
+ - En errores anidados agrega rutas como [0], [1].name.
330
369
 
331
- ### Object / ObjectNotNull
370
+ ### Object y ObjectNotNull
332
371
 
333
372
  Firma:
334
373
 
335
374
  ```ts
336
- const o1 = V.Object(properties, conditions?);
337
- const o2 = V.ObjectNotNull(properties, conditions?);
338
- ```
339
-
340
- Ejemplo:
341
-
342
- ```ts
343
- const user = V.ObjectNotNull(
375
+ const userV = V.Object(
344
376
  {
345
- name: V.StringNotNull({ minLength: 3 }),
346
- age: V.NumberNotNull({ min: 18 }),
377
+ name: V.StringNotNull(),
378
+ age: V.Number(),
347
379
  },
348
380
  {
349
381
  strictMode: true,
350
- ignoreCase: true,
382
+ ignoreCase: false,
351
383
  takeAllValues: false,
352
384
  },
353
385
  );
354
386
  ```
355
387
 
388
+ Retorno:
389
+
390
+ - VObject: objeto tipado | null
391
+ - VObjectNotNull: objeto tipado
392
+
356
393
  Condiciones:
357
394
 
358
395
  - invalidPropertyMessage
@@ -365,16 +402,106 @@ Condiciones:
365
402
  - defaultValue
366
403
  - badTypeMessage
367
404
 
368
- Notas:
405
+ Comportamiento clave:
406
+
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 una validacion final con el objeto ya validado.
411
+
412
+ ### Any
413
+
414
+ Retorno:
415
+
416
+ - VAny: any | null
417
+
418
+ Condiciones:
419
+
420
+ - isRequired
421
+ - emptyAsNull
422
+ - defaultValue
423
+ - badTypeMessage
424
+
425
+ ## Transformaciones de valores
426
+
427
+ La clase base Verifier incluye transform(mapper), que permite postprocesar la salida validada sin perder la validacion previa.
428
+
429
+ String y StringNotNull incluyen helpers listos:
430
+
431
+ - trim
432
+ - trimStart
433
+ - trimEnd
434
+ - toLowerCase
435
+ - toUpperCase
436
+ - removeAccents
437
+ - padStart
438
+ - padEnd
439
+
440
+ Ejemplo:
441
+
442
+ ```ts
443
+ const usernameV = V.StringNotNull({ minLength: 3 })
444
+ .trim()
445
+ .toLowerCase()
446
+ .removeAccents();
447
+ ```
448
+
449
+ ## Tipado inferido
450
+
451
+ ### InferType
452
+
453
+ ```ts
454
+ import { InferType, Verifiers as V } from "structure-verifier";
455
+
456
+ const schema = V.ObjectNotNull({
457
+ id: V.UUIDNotNull(),
458
+ profile: V.ObjectNotNull({
459
+ name: V.StringNotNull(),
460
+ age: V.Number(),
461
+ }),
462
+ });
463
+
464
+ type User = InferType<typeof schema>;
465
+ ```
466
+
467
+ ### InferFactoryType
468
+
469
+ ```ts
470
+ import { InferFactoryType, Verifiers as V } from "structure-verifier";
471
+
472
+ type NumberMaybe = InferFactoryType<typeof V.Number>;
473
+ type NumberRequired = InferFactoryType<typeof V.NumberNotNull>;
474
+ ```
475
+
476
+ ## Manejo de errores
477
+
478
+ Cuando una validacion falla se lanza VerificationError.
479
+
480
+ Propiedades principales:
369
481
 
370
- - strictMode rechaza propiedades extra.
371
- - ignoreCase permite mapear propiedades sin importar mayusculas/minusculas.
372
- - takeAllValues conserva propiedades no definidas en el esquema.
373
- - conds ejecuta una validacion adicional al final con el objeto ya tipado.
482
+ - message: todos los errores concatenados por punto y coma.
483
+ - errors: arreglo de mensajes planos.
484
+ - errorsObj: arreglo de objetos con key, message y metadatos.
485
+
486
+ Ejemplo:
487
+
488
+ ```ts
489
+ try {
490
+ V.ObjectNotNull({
491
+ name: V.StringNotNull({ minLength: 3 }),
492
+ tags: V.ArrayNotNull(V.StringNotNull(), { minLength: 1 }),
493
+ }).check({ name: "Al", tags: [] });
494
+ } catch (error) {
495
+ if (error instanceof VerificationError) {
496
+ console.log(error.errors);
497
+ console.log(error.errorsObj);
498
+ }
499
+ }
500
+ ```
374
501
 
375
502
  ## datetime (dayjs)
376
503
 
377
- La libreria re-exporta dayjs como datetime con plugins:
504
+ La libreria exporta dayjs como datetime con plugins activados:
378
505
 
379
506
  - utc
380
507
  - timezone
@@ -386,11 +513,58 @@ Ejemplo:
386
513
  import { datetime } from "structure-verifier";
387
514
 
388
515
  const now = datetime();
389
- console.log(now.tz("UTC").format());
516
+ const utc = now.tz("UTC").format();
517
+ console.log(utc);
390
518
  ```
391
519
 
392
- ## Ejecutar tests del proyecto
520
+ ## Ejemplos avanzados
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
544
+
545
+ ```ts
546
+ const personV = V.ObjectNotNull(
547
+ {
548
+ age: V.NumberNotNull({ min: 0 }),
549
+ hasParentalConsent: V.Boolean(),
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
393
562
 
394
563
  ```bash
395
564
  npm test
565
+ npm run dev
396
566
  ```
567
+
568
+ ## Licencia
569
+
570
+ ISC