@linktic/validator 1.0.0 → 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/README.md CHANGED
@@ -54,11 +54,27 @@ v.schema({
54
54
  age: { required: true, type: 'number', label: 'Edad', min: 18, max: 120 },
55
55
  role: { required: true, label: 'Rol', enum: ['admin', 'user', 'viewer'] },
56
56
  notes: { required: false, type: 'string', label: 'Notas', maxLength: 500 },
57
+ tags: { required: true, type: 'array', arrayOf: 'string', label: 'Etiquetas' },
57
58
  })
58
59
 
59
60
  v.validate()
60
61
  ```
61
62
 
63
+ ## Validacion de tipo de elementos en arrays
64
+
65
+ ```typescript
66
+ // Array de strings
67
+ v.field('tags', 'Etiquetas').required().array().arrayOf('string')
68
+
69
+ // Array de numeros
70
+ v.field('scores', 'Puntajes').required().array().arrayOf('number')
71
+
72
+ // Array de objetos
73
+ v.field('items', 'Elementos').required().array().arrayOf('object')
74
+ ```
75
+
76
+ Tipos soportados: `'string'` | `'number'` | `'object'`
77
+
62
78
  ## Campos anidados
63
79
 
64
80
  ```typescript
@@ -111,6 +127,7 @@ const english: ValidationMessageMap = {
111
127
  number: (field) => `${field} must be a number`,
112
128
  boolean: (field) => `${field} must be true or false`,
113
129
  array: (field) => `${field} must be a list`,
130
+ arrayOf: (field, type) => `${field} must be a list of ${type}`,
114
131
  object: (field) => `${field} must be an object`,
115
132
  uuid: (field) => `${field} must be a valid identifier`,
116
133
  enum: (field, values) => `${field} must be one of: ${values.join(', ')}`,
@@ -139,6 +156,7 @@ resetMessages() // Vuelve a espanol
139
156
  | `number(msg?)` | Debe ser number |
140
157
  | `boolean(msg?)` | Debe ser boolean |
141
158
  | `array(msg?)` | Debe ser array |
159
+ | `arrayOf(type, msg?)` | Elementos del array deben ser del tipo (`'string'` \| `'number'` \| `'object'`) |
142
160
  | `object(msg?)` | Debe ser objeto (no array) |
143
161
  | `date(msg?)` | Debe ser fecha valida |
144
162
  | `email(msg?)` | Debe ser email valido |
@@ -35,6 +35,7 @@ var spanishMessages = {
35
35
  number: (campo) => `${campo} debe ser un n\xFAmero`,
36
36
  boolean: (campo) => `${campo} debe ser verdadero o falso`,
37
37
  array: (campo) => `${campo} debe ser una lista`,
38
+ arrayOf: (campo, tipo) => `${campo} debe ser una lista de ${tipo}`,
38
39
  object: (campo) => `${campo} debe ser un objeto`,
39
40
  uuid: (campo) => `${campo} debe ser un identificador v\xE1lido`,
40
41
  enum: (campo, valores) => `${campo} debe ser uno de: ${valores.join(", ")}`,
@@ -37,6 +37,7 @@ var spanishMessages = {
37
37
  number: (campo) => `${campo} debe ser un n\xFAmero`,
38
38
  boolean: (campo) => `${campo} debe ser verdadero o falso`,
39
39
  array: (campo) => `${campo} debe ser una lista`,
40
+ arrayOf: (campo, tipo) => `${campo} debe ser una lista de ${tipo}`,
40
41
  object: (campo) => `${campo} debe ser un objeto`,
41
42
  uuid: (campo) => `${campo} debe ser un identificador v\xE1lido`,
42
43
  enum: (campo, valores) => `${campo} debe ser uno de: ${valores.join(", ")}`,
@@ -11,6 +11,7 @@ interface ValidationMessageMap {
11
11
  number: (campo: string) => string;
12
12
  boolean: (campo: string) => string;
13
13
  array: (campo: string) => string;
14
+ arrayOf: (campo: string, tipo: string) => string;
14
15
  object: (campo: string) => string;
15
16
  uuid: (campo: string) => string;
16
17
  enum: (campo: string, valores: unknown[]) => string;
@@ -11,6 +11,7 @@ interface ValidationMessageMap {
11
11
  number: (campo: string) => string;
12
12
  boolean: (campo: string) => string;
13
13
  array: (campo: string) => string;
14
+ arrayOf: (campo: string, tipo: string) => string;
14
15
  object: (campo: string) => string;
15
16
  uuid: (campo: string) => string;
16
17
  enum: (campo: string, valores: unknown[]) => string;
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGGX2GQQ6_cjs = require('./chunk-GGX2GQQ6.cjs');
3
+ var chunkVKEK7472_cjs = require('./chunk-VKEK7472.cjs');
4
4
 
5
5
  // src/errors/DomainError.ts
6
6
  var DomainError = class extends Error {
@@ -38,7 +38,7 @@ var ValidationError = class _ValidationError extends DomainError {
38
38
  };
39
39
 
40
40
  // src/messages/index.ts
41
- var currentMessages = { ...chunkGGX2GQQ6_cjs.spanishMessages };
41
+ var currentMessages = { ...chunkVKEK7472_cjs.spanishMessages };
42
42
  function setMessages(messages) {
43
43
  currentMessages = { ...messages };
44
44
  }
@@ -46,7 +46,7 @@ function configure(overrides) {
46
46
  currentMessages = { ...currentMessages, ...overrides };
47
47
  }
48
48
  function resetMessages() {
49
- currentMessages = { ...chunkGGX2GQQ6_cjs.spanishMessages };
49
+ currentMessages = { ...chunkVKEK7472_cjs.spanishMessages };
50
50
  }
51
51
  function getMessages() {
52
52
  return currentMessages;
@@ -66,6 +66,7 @@ var ValidationMessages = {
66
66
  number: (campo) => getMessages().number(campo),
67
67
  boolean: (campo) => getMessages().boolean(campo),
68
68
  array: (campo) => getMessages().array(campo),
69
+ arrayOf: (campo, tipo) => getMessages().arrayOf(campo, tipo),
69
70
  object: (campo) => getMessages().object(campo),
70
71
  uuid: (campo) => getMessages().uuid(campo),
71
72
  enum: (campo, valores) => getMessages().enum(campo, valores),
@@ -161,6 +162,29 @@ var FieldValidator = class {
161
162
  }
162
163
  return this;
163
164
  }
165
+ arrayOf(itemType, message) {
166
+ if (this.shouldSkip()) return this;
167
+ if (!this.isEmpty && Array.isArray(this.value)) {
168
+ const typeLabels = {
169
+ string: "textos",
170
+ number: "n\xFAmeros",
171
+ object: "objetos"
172
+ };
173
+ const isValid = this.value.every((item) => {
174
+ if (itemType === "object") {
175
+ return item !== null && typeof item === "object" && !Array.isArray(item);
176
+ }
177
+ return typeof item === itemType;
178
+ });
179
+ if (!isValid) {
180
+ this.addError(
181
+ "arrayOf",
182
+ message ?? ValidationMessages.arrayOf(this.fieldLabel, typeLabels[itemType])
183
+ );
184
+ }
185
+ }
186
+ return this;
187
+ }
164
188
  object(message) {
165
189
  if (this.shouldSkip()) return this;
166
190
  if (!this.isEmpty && (typeof this.value !== "object" || Array.isArray(this.value))) {
@@ -397,6 +421,9 @@ var Validator = class {
397
421
  if (rules.enum) {
398
422
  fieldValidator.enum(rules.enum, messages.enum);
399
423
  }
424
+ if (rules.arrayOf) {
425
+ fieldValidator.arrayOf(rules.arrayOf, messages.arrayOf);
426
+ }
400
427
  if (rules.allowedChars) {
401
428
  fieldValidator.allowedChars(rules.allowedChars, messages.allowedChars);
402
429
  }
@@ -437,11 +464,11 @@ var validate = (data, options) => {
437
464
 
438
465
  Object.defineProperty(exports, "interpolate", {
439
466
  enumerable: true,
440
- get: function () { return chunkGGX2GQQ6_cjs.interpolate; }
467
+ get: function () { return chunkVKEK7472_cjs.interpolate; }
441
468
  });
442
469
  Object.defineProperty(exports, "spanishMessages", {
443
470
  enumerable: true,
444
- get: function () { return chunkGGX2GQQ6_cjs.spanishMessages; }
471
+ get: function () { return chunkVKEK7472_cjs.spanishMessages; }
445
472
  });
446
473
  exports.DomainError = DomainError;
447
474
  exports.ValidationError = ValidationError;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as ValidationMessageMap } from './es-QPgrpTLv.cjs';
2
- export { s as spanishMessages } from './es-QPgrpTLv.cjs';
1
+ import { V as ValidationMessageMap } from './es-BnsUFBqD.cjs';
2
+ export { s as spanishMessages } from './es-BnsUFBqD.cjs';
3
3
 
4
4
  interface ValidationFieldError {
5
5
  field: string;
@@ -9,6 +9,7 @@ interface ValidationFieldError {
9
9
  }
10
10
 
11
11
  type ValidationType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'email' | 'uuid';
12
+ type ArrayItemType = 'string' | 'number' | 'object';
12
13
  interface ValidationRuleConfig {
13
14
  required?: boolean;
14
15
  type?: ValidationType;
@@ -20,6 +21,7 @@ interface ValidationRuleConfig {
20
21
  patternExample?: string;
21
22
  enum?: unknown[];
22
23
  allowedChars?: string;
24
+ arrayOf?: ArrayItemType;
23
25
  custom?: (value: unknown) => boolean | string;
24
26
  }
25
27
  interface FieldValidationConfig extends ValidationRuleConfig {
@@ -60,6 +62,7 @@ declare class FieldValidator {
60
62
  number(message?: string): this;
61
63
  boolean(message?: string): this;
62
64
  array(message?: string): this;
65
+ arrayOf(itemType: ArrayItemType, message?: string): this;
63
66
  object(message?: string): this;
64
67
  type(expectedType: ValidationType, message?: string): this;
65
68
  minLength(min: number, message?: string): this;
@@ -125,6 +128,7 @@ declare const ValidationMessages: {
125
128
  number: (campo: string) => string;
126
129
  boolean: (campo: string) => string;
127
130
  array: (campo: string) => string;
131
+ arrayOf: (campo: string, tipo: string) => string;
128
132
  object: (campo: string) => string;
129
133
  uuid: (campo: string) => string;
130
134
  enum: (campo: string, valores: unknown[]) => string;
@@ -156,4 +160,4 @@ declare function resetMessages(): void;
156
160
  */
157
161
  declare function getMessages(): ValidationMessageMap;
158
162
 
159
- export { DomainError, type FieldValidationConfig, type SchemaValidationConfig, ValidationError, type ValidationFieldError, ValidationMessageMap, ValidationMessages, type ValidationResult, type ValidationRuleConfig, type ValidationType, Validator, configure, getMessages, interpolate, resetMessages, setMessages, validate };
163
+ export { type ArrayItemType, DomainError, type FieldValidationConfig, type SchemaValidationConfig, ValidationError, type ValidationFieldError, ValidationMessageMap, ValidationMessages, type ValidationResult, type ValidationRuleConfig, type ValidationType, Validator, configure, getMessages, interpolate, resetMessages, setMessages, validate };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as ValidationMessageMap } from './es-QPgrpTLv.js';
2
- export { s as spanishMessages } from './es-QPgrpTLv.js';
1
+ import { V as ValidationMessageMap } from './es-BnsUFBqD.js';
2
+ export { s as spanishMessages } from './es-BnsUFBqD.js';
3
3
 
4
4
  interface ValidationFieldError {
5
5
  field: string;
@@ -9,6 +9,7 @@ interface ValidationFieldError {
9
9
  }
10
10
 
11
11
  type ValidationType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'email' | 'uuid';
12
+ type ArrayItemType = 'string' | 'number' | 'object';
12
13
  interface ValidationRuleConfig {
13
14
  required?: boolean;
14
15
  type?: ValidationType;
@@ -20,6 +21,7 @@ interface ValidationRuleConfig {
20
21
  patternExample?: string;
21
22
  enum?: unknown[];
22
23
  allowedChars?: string;
24
+ arrayOf?: ArrayItemType;
23
25
  custom?: (value: unknown) => boolean | string;
24
26
  }
25
27
  interface FieldValidationConfig extends ValidationRuleConfig {
@@ -60,6 +62,7 @@ declare class FieldValidator {
60
62
  number(message?: string): this;
61
63
  boolean(message?: string): this;
62
64
  array(message?: string): this;
65
+ arrayOf(itemType: ArrayItemType, message?: string): this;
63
66
  object(message?: string): this;
64
67
  type(expectedType: ValidationType, message?: string): this;
65
68
  minLength(min: number, message?: string): this;
@@ -125,6 +128,7 @@ declare const ValidationMessages: {
125
128
  number: (campo: string) => string;
126
129
  boolean: (campo: string) => string;
127
130
  array: (campo: string) => string;
131
+ arrayOf: (campo: string, tipo: string) => string;
128
132
  object: (campo: string) => string;
129
133
  uuid: (campo: string) => string;
130
134
  enum: (campo: string, valores: unknown[]) => string;
@@ -156,4 +160,4 @@ declare function resetMessages(): void;
156
160
  */
157
161
  declare function getMessages(): ValidationMessageMap;
158
162
 
159
- export { DomainError, type FieldValidationConfig, type SchemaValidationConfig, ValidationError, type ValidationFieldError, ValidationMessageMap, ValidationMessages, type ValidationResult, type ValidationRuleConfig, type ValidationType, Validator, configure, getMessages, interpolate, resetMessages, setMessages, validate };
163
+ export { type ArrayItemType, DomainError, type FieldValidationConfig, type SchemaValidationConfig, ValidationError, type ValidationFieldError, ValidationMessageMap, ValidationMessages, type ValidationResult, type ValidationRuleConfig, type ValidationType, Validator, configure, getMessages, interpolate, resetMessages, setMessages, validate };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { spanishMessages } from './chunk-5LU5LI4H.js';
2
- export { interpolate, spanishMessages } from './chunk-5LU5LI4H.js';
1
+ import { spanishMessages } from './chunk-LWLCOEMA.js';
2
+ export { interpolate, spanishMessages } from './chunk-LWLCOEMA.js';
3
3
 
4
4
  // src/errors/DomainError.ts
5
5
  var DomainError = class extends Error {
@@ -65,6 +65,7 @@ var ValidationMessages = {
65
65
  number: (campo) => getMessages().number(campo),
66
66
  boolean: (campo) => getMessages().boolean(campo),
67
67
  array: (campo) => getMessages().array(campo),
68
+ arrayOf: (campo, tipo) => getMessages().arrayOf(campo, tipo),
68
69
  object: (campo) => getMessages().object(campo),
69
70
  uuid: (campo) => getMessages().uuid(campo),
70
71
  enum: (campo, valores) => getMessages().enum(campo, valores),
@@ -160,6 +161,29 @@ var FieldValidator = class {
160
161
  }
161
162
  return this;
162
163
  }
164
+ arrayOf(itemType, message) {
165
+ if (this.shouldSkip()) return this;
166
+ if (!this.isEmpty && Array.isArray(this.value)) {
167
+ const typeLabels = {
168
+ string: "textos",
169
+ number: "n\xFAmeros",
170
+ object: "objetos"
171
+ };
172
+ const isValid = this.value.every((item) => {
173
+ if (itemType === "object") {
174
+ return item !== null && typeof item === "object" && !Array.isArray(item);
175
+ }
176
+ return typeof item === itemType;
177
+ });
178
+ if (!isValid) {
179
+ this.addError(
180
+ "arrayOf",
181
+ message ?? ValidationMessages.arrayOf(this.fieldLabel, typeLabels[itemType])
182
+ );
183
+ }
184
+ }
185
+ return this;
186
+ }
163
187
  object(message) {
164
188
  if (this.shouldSkip()) return this;
165
189
  if (!this.isEmpty && (typeof this.value !== "object" || Array.isArray(this.value))) {
@@ -396,6 +420,9 @@ var Validator = class {
396
420
  if (rules.enum) {
397
421
  fieldValidator.enum(rules.enum, messages.enum);
398
422
  }
423
+ if (rules.arrayOf) {
424
+ fieldValidator.arrayOf(rules.arrayOf, messages.arrayOf);
425
+ }
399
426
  if (rules.allowedChars) {
400
427
  fieldValidator.allowedChars(rules.allowedChars, messages.allowedChars);
401
428
  }
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunkGGX2GQQ6_cjs = require('../chunk-GGX2GQQ6.cjs');
3
+ var chunkVKEK7472_cjs = require('../chunk-VKEK7472.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "spanishMessages", {
8
8
  enumerable: true,
9
- get: function () { return chunkGGX2GQQ6_cjs.spanishMessages; }
9
+ get: function () { return chunkVKEK7472_cjs.spanishMessages; }
10
10
  });
@@ -1 +1 @@
1
- export { s as spanishMessages } from '../es-QPgrpTLv.cjs';
1
+ export { s as spanishMessages } from '../es-BnsUFBqD.cjs';
@@ -1 +1 @@
1
- export { s as spanishMessages } from '../es-QPgrpTLv.js';
1
+ export { s as spanishMessages } from '../es-BnsUFBqD.js';
@@ -1 +1 @@
1
- export { spanishMessages } from '../chunk-5LU5LI4H.js';
1
+ export { spanishMessages } from '../chunk-LWLCOEMA.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linktic/validator",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Framework-agnostic TypeScript validation library with fluent API and configurable Spanish default messages",
5
5
  "author": "LinkTIC",
6
6
  "license": "UNLICENSED",
@@ -25,9 +25,7 @@
25
25
  },
26
26
  "typesVersions": {
27
27
  "*": {
28
- "messages/es": [
29
- "./dist/messages/es.d.ts"
30
- ]
28
+ "messages/es": ["./dist/messages/es.d.ts"]
31
29
  }
32
30
  },
33
31
  "files": [
@@ -37,6 +35,17 @@
37
35
  "engines": {
38
36
  "node": ">=18.0.0"
39
37
  },
38
+ "scripts": {
39
+ "build": "tsup",
40
+ "clean": "rm -rf dist",
41
+ "prebuild": "npm run clean",
42
+ "dev": "tsup --watch",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "test:coverage": "vitest run --coverage",
46
+ "prepublishOnly": "npm run test && npm run build",
47
+ "typecheck": "tsc --noEmit"
48
+ },
40
49
  "devDependencies": {
41
50
  "tsup": "^8.0.0",
42
51
  "typescript": "~5.6.0",
@@ -48,15 +57,5 @@
48
57
  "typescript",
49
58
  "fluent-api",
50
59
  "linktic"
51
- ],
52
- "scripts": {
53
- "build": "tsup",
54
- "clean": "rm -rf dist",
55
- "prebuild": "npm run clean",
56
- "dev": "tsup --watch",
57
- "test": "vitest run",
58
- "test:watch": "vitest",
59
- "test:coverage": "vitest run --coverage",
60
- "typecheck": "tsc --noEmit"
61
- }
62
- }
60
+ ]
61
+ }