@excofy/utils 1.0.8 → 1.0.10

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.cjs CHANGED
@@ -311,6 +311,41 @@ function createValidator() {
311
311
  }
312
312
  return validator;
313
313
  },
314
+ expirationDate: (message) => {
315
+ if (shouldSkipValidation()) {
316
+ return validator;
317
+ }
318
+ if (typeof current.value === "string") {
319
+ const expirationDate = current.value;
320
+ const regex = /^(\d{2})\/(\d{2}|\d{4})$/;
321
+ const match = expirationDate.match(regex);
322
+ if (!match) {
323
+ current.pushError(message);
324
+ return validator;
325
+ }
326
+ const month = Number.parseInt(match[1], 10);
327
+ let year = Number.parseInt(match[2], 10);
328
+ if (month < 1 || month > 12) {
329
+ current.pushError(message);
330
+ return validator;
331
+ }
332
+ const now = /* @__PURE__ */ new Date();
333
+ const currentYear = now.getFullYear();
334
+ const currentMonth = now.getMonth() + 1;
335
+ if (year < 100) {
336
+ const century = Math.floor(currentYear / 100) * 100;
337
+ year += century;
338
+ if (year < currentYear) year += 100;
339
+ }
340
+ if (year < currentYear || year === currentYear && month < currentMonth) {
341
+ current.pushError(message);
342
+ return validator;
343
+ }
344
+ } else {
345
+ current.pushError(message);
346
+ }
347
+ return validator;
348
+ },
314
349
  fileMaxSize: (maxSize, message) => {
315
350
  if (shouldSkipValidation()) {
316
351
  return validator;
package/dist/index.d.cts CHANGED
@@ -17,6 +17,35 @@ type TTypes = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'file' | 'd
17
17
  interface IInputErrors {
18
18
  [key: string]: TMessage[] | IInputErrors[];
19
19
  }
20
+ interface ValidatorField {
21
+ cnpj(message: string): ValidatorField;
22
+ cpf(message: string): ValidatorField;
23
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): ValidatorField;
24
+ email(message: string): ValidatorField;
25
+ expirationDate(message: string): ValidatorField;
26
+ fileMaxSize(maxSize: number, message: string): ValidatorField;
27
+ fileType(validTypes: string[], message: string): ValidatorField;
28
+ length(length: number, message: string): ValidatorField;
29
+ min(min: number, message: string): ValidatorField;
30
+ max(max: number, message: string): ValidatorField;
31
+ transform<U>(fn: (value: TInputValue) => U): ValidatorField;
32
+ slug(message: string): ValidatorField;
33
+ sanitize(): ValidatorField;
34
+ sanitizePreservingNewlines(): ValidatorField;
35
+ sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
36
+ url(message: string): ValidatorField;
37
+ uuid(message: string): ValidatorField;
38
+ oneOf(types: string[], message: string): ValidatorField;
39
+ test(validateFn: (value: TValue, context: {
40
+ field: string;
41
+ }) => boolean, message: string): ValidatorField;
42
+ videoUrl: {
43
+ youtube(message: string): ValidatorField;
44
+ };
45
+ asNumber(message: string): ValidatorField;
46
+ asBoolean(message: string): ValidatorField;
47
+ asStringArray(message: string): ValidatorField;
48
+ }
20
49
  /**
21
50
  * Cria um validador de inputs com suporte a validações encadeadas, transformação e sanitização.
22
51
  *
@@ -43,94 +72,13 @@ declare function createValidator<TRaw extends Record<string, TInputValue>, TPars
43
72
  unflattenErrors(flat: Record<string, TMessage[]>): Record<string, unknown>;
44
73
  validate<K extends keyof TRaw>(field: K): {
45
74
  isRequired(message: string): {
46
- type(type: TTypes, message: string): {
47
- cnpj: (message: string) => /*elided*/ any;
48
- cpf: (message: string) => /*elided*/ any;
49
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
50
- email: (message: string) => /*elided*/ any;
51
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
52
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
53
- length(length: number, message: string): /*elided*/ any;
54
- min(min: number, message: string): /*elided*/ any;
55
- max(max: number, message: string): /*elided*/ any;
56
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
57
- slug(message: string): /*elided*/ any;
58
- sanitize(): /*elided*/ any;
59
- sanitizePreservingNewlines(): /*elided*/ any;
60
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
61
- url(message: string): /*elided*/ any;
62
- uuid(message: string): /*elided*/ any;
63
- oneOf: (types: string[], message: string) => /*elided*/ any;
64
- test(validateFn: (value: TInputValue, context: {
65
- field: string;
66
- }) => boolean, message: string): /*elided*/ any;
67
- videoUrl: {
68
- youtube(message: string): /*elided*/ any;
69
- };
70
- asNumber(message: string): /*elided*/ any;
71
- asBoolean(message: string): /*elided*/ any;
72
- asStringArray(message: string): /*elided*/ any;
73
- };
75
+ type(type: TTypes, message: string): ValidatorField;
74
76
  };
75
77
  isNotRequired(): {
76
- type(type: TTypes, message: string): {
77
- cnpj: (message: string) => /*elided*/ any;
78
- cpf: (message: string) => /*elided*/ any;
79
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
80
- email: (message: string) => /*elided*/ any;
81
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
82
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
83
- length(length: number, message: string): /*elided*/ any;
84
- min(min: number, message: string): /*elided*/ any;
85
- max(max: number, message: string): /*elided*/ any;
86
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
87
- slug(message: string): /*elided*/ any;
88
- sanitize(): /*elided*/ any;
89
- sanitizePreservingNewlines(): /*elided*/ any;
90
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
91
- url(message: string): /*elided*/ any;
92
- uuid(message: string): /*elided*/ any;
93
- oneOf: (types: string[], message: string) => /*elided*/ any;
94
- test(validateFn: (value: TInputValue, context: {
95
- field: string;
96
- }) => boolean, message: string): /*elided*/ any;
97
- videoUrl: {
98
- youtube(message: string): /*elided*/ any;
99
- };
100
- asNumber(message: string): /*elided*/ any;
101
- asBoolean(message: string): /*elided*/ any;
102
- asStringArray(message: string): /*elided*/ any;
103
- };
78
+ type(type: TTypes, message: string): ValidatorField;
104
79
  };
105
80
  conditionallyRequired(isRequired: boolean, message: string): {
106
- type(type: TTypes, message: string): {
107
- cnpj: (message: string) => /*elided*/ any;
108
- cpf: (message: string) => /*elided*/ any;
109
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
110
- email: (message: string) => /*elided*/ any;
111
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
112
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
113
- length(length: number, message: string): /*elided*/ any;
114
- min(min: number, message: string): /*elided*/ any;
115
- max(max: number, message: string): /*elided*/ any;
116
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
117
- slug(message: string): /*elided*/ any;
118
- sanitize(): /*elided*/ any;
119
- sanitizePreservingNewlines(): /*elided*/ any;
120
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
121
- url(message: string): /*elided*/ any;
122
- uuid(message: string): /*elided*/ any;
123
- oneOf: (types: string[], message: string) => /*elided*/ any;
124
- test(validateFn: (value: TInputValue, context: {
125
- field: string;
126
- }) => boolean, message: string): /*elided*/ any;
127
- videoUrl: {
128
- youtube(message: string): /*elided*/ any;
129
- };
130
- asNumber(message: string): /*elided*/ any;
131
- asBoolean(message: string): /*elided*/ any;
132
- asStringArray(message: string): /*elided*/ any;
133
- };
81
+ type(type: TTypes, message: string): ValidatorField;
134
82
  };
135
83
  };
136
84
  };
package/dist/index.d.ts CHANGED
@@ -17,6 +17,35 @@ type TTypes = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'file' | 'd
17
17
  interface IInputErrors {
18
18
  [key: string]: TMessage[] | IInputErrors[];
19
19
  }
20
+ interface ValidatorField {
21
+ cnpj(message: string): ValidatorField;
22
+ cpf(message: string): ValidatorField;
23
+ each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): ValidatorField;
24
+ email(message: string): ValidatorField;
25
+ expirationDate(message: string): ValidatorField;
26
+ fileMaxSize(maxSize: number, message: string): ValidatorField;
27
+ fileType(validTypes: string[], message: string): ValidatorField;
28
+ length(length: number, message: string): ValidatorField;
29
+ min(min: number, message: string): ValidatorField;
30
+ max(max: number, message: string): ValidatorField;
31
+ transform<U>(fn: (value: TInputValue) => U): ValidatorField;
32
+ slug(message: string): ValidatorField;
33
+ sanitize(): ValidatorField;
34
+ sanitizePreservingNewlines(): ValidatorField;
35
+ sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
36
+ url(message: string): ValidatorField;
37
+ uuid(message: string): ValidatorField;
38
+ oneOf(types: string[], message: string): ValidatorField;
39
+ test(validateFn: (value: TValue, context: {
40
+ field: string;
41
+ }) => boolean, message: string): ValidatorField;
42
+ videoUrl: {
43
+ youtube(message: string): ValidatorField;
44
+ };
45
+ asNumber(message: string): ValidatorField;
46
+ asBoolean(message: string): ValidatorField;
47
+ asStringArray(message: string): ValidatorField;
48
+ }
20
49
  /**
21
50
  * Cria um validador de inputs com suporte a validações encadeadas, transformação e sanitização.
22
51
  *
@@ -43,94 +72,13 @@ declare function createValidator<TRaw extends Record<string, TInputValue>, TPars
43
72
  unflattenErrors(flat: Record<string, TMessage[]>): Record<string, unknown>;
44
73
  validate<K extends keyof TRaw>(field: K): {
45
74
  isRequired(message: string): {
46
- type(type: TTypes, message: string): {
47
- cnpj: (message: string) => /*elided*/ any;
48
- cpf: (message: string) => /*elided*/ any;
49
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
50
- email: (message: string) => /*elided*/ any;
51
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
52
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
53
- length(length: number, message: string): /*elided*/ any;
54
- min(min: number, message: string): /*elided*/ any;
55
- max(max: number, message: string): /*elided*/ any;
56
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
57
- slug(message: string): /*elided*/ any;
58
- sanitize(): /*elided*/ any;
59
- sanitizePreservingNewlines(): /*elided*/ any;
60
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
61
- url(message: string): /*elided*/ any;
62
- uuid(message: string): /*elided*/ any;
63
- oneOf: (types: string[], message: string) => /*elided*/ any;
64
- test(validateFn: (value: TInputValue, context: {
65
- field: string;
66
- }) => boolean, message: string): /*elided*/ any;
67
- videoUrl: {
68
- youtube(message: string): /*elided*/ any;
69
- };
70
- asNumber(message: string): /*elided*/ any;
71
- asBoolean(message: string): /*elided*/ any;
72
- asStringArray(message: string): /*elided*/ any;
73
- };
75
+ type(type: TTypes, message: string): ValidatorField;
74
76
  };
75
77
  isNotRequired(): {
76
- type(type: TTypes, message: string): {
77
- cnpj: (message: string) => /*elided*/ any;
78
- cpf: (message: string) => /*elided*/ any;
79
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
80
- email: (message: string) => /*elided*/ any;
81
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
82
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
83
- length(length: number, message: string): /*elided*/ any;
84
- min(min: number, message: string): /*elided*/ any;
85
- max(max: number, message: string): /*elided*/ any;
86
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
87
- slug(message: string): /*elided*/ any;
88
- sanitize(): /*elided*/ any;
89
- sanitizePreservingNewlines(): /*elided*/ any;
90
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
91
- url(message: string): /*elided*/ any;
92
- uuid(message: string): /*elided*/ any;
93
- oneOf: (types: string[], message: string) => /*elided*/ any;
94
- test(validateFn: (value: TInputValue, context: {
95
- field: string;
96
- }) => boolean, message: string): /*elided*/ any;
97
- videoUrl: {
98
- youtube(message: string): /*elided*/ any;
99
- };
100
- asNumber(message: string): /*elided*/ any;
101
- asBoolean(message: string): /*elided*/ any;
102
- asStringArray(message: string): /*elided*/ any;
103
- };
78
+ type(type: TTypes, message: string): ValidatorField;
104
79
  };
105
80
  conditionallyRequired(isRequired: boolean, message: string): {
106
- type(type: TTypes, message: string): {
107
- cnpj: (message: string) => /*elided*/ any;
108
- cpf: (message: string) => /*elided*/ any;
109
- each(callback: <U extends Record<string, TInputValue>>(item: U, index: number, subValidator: ReturnType<typeof createValidator<U>>) => void): /*elided*/ any;
110
- email: (message: string) => /*elided*/ any;
111
- fileMaxSize: (maxSize: number, message: string) => /*elided*/ any;
112
- fileType: (validTypes: string[], message: string) => /*elided*/ any;
113
- length(length: number, message: string): /*elided*/ any;
114
- min(min: number, message: string): /*elided*/ any;
115
- max(max: number, message: string): /*elided*/ any;
116
- transform<U>(fn: (value: TInputValue) => U): /*elided*/ any;
117
- slug(message: string): /*elided*/ any;
118
- sanitize(): /*elided*/ any;
119
- sanitizePreservingNewlines(): /*elided*/ any;
120
- sanitizeHTML(tags?: AllowedTag[]): /*elided*/ any;
121
- url(message: string): /*elided*/ any;
122
- uuid(message: string): /*elided*/ any;
123
- oneOf: (types: string[], message: string) => /*elided*/ any;
124
- test(validateFn: (value: TInputValue, context: {
125
- field: string;
126
- }) => boolean, message: string): /*elided*/ any;
127
- videoUrl: {
128
- youtube(message: string): /*elided*/ any;
129
- };
130
- asNumber(message: string): /*elided*/ any;
131
- asBoolean(message: string): /*elided*/ any;
132
- asStringArray(message: string): /*elided*/ any;
133
- };
81
+ type(type: TTypes, message: string): ValidatorField;
134
82
  };
135
83
  };
136
84
  };
package/dist/index.js CHANGED
@@ -277,6 +277,41 @@ function createValidator() {
277
277
  }
278
278
  return validator;
279
279
  },
280
+ expirationDate: (message) => {
281
+ if (shouldSkipValidation()) {
282
+ return validator;
283
+ }
284
+ if (typeof current.value === "string") {
285
+ const expirationDate = current.value;
286
+ const regex = /^(\d{2})\/(\d{2}|\d{4})$/;
287
+ const match = expirationDate.match(regex);
288
+ if (!match) {
289
+ current.pushError(message);
290
+ return validator;
291
+ }
292
+ const month = Number.parseInt(match[1], 10);
293
+ let year = Number.parseInt(match[2], 10);
294
+ if (month < 1 || month > 12) {
295
+ current.pushError(message);
296
+ return validator;
297
+ }
298
+ const now = /* @__PURE__ */ new Date();
299
+ const currentYear = now.getFullYear();
300
+ const currentMonth = now.getMonth() + 1;
301
+ if (year < 100) {
302
+ const century = Math.floor(currentYear / 100) * 100;
303
+ year += century;
304
+ if (year < currentYear) year += 100;
305
+ }
306
+ if (year < currentYear || year === currentYear && month < currentMonth) {
307
+ current.pushError(message);
308
+ return validator;
309
+ }
310
+ } else {
311
+ current.pushError(message);
312
+ }
313
+ return validator;
314
+ },
280
315
  fileMaxSize: (maxSize, message) => {
281
316
  if (shouldSkipValidation()) {
282
317
  return validator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@excofy/utils",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Biblioteca de utilitários para o Excofy",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -18,6 +18,43 @@ interface IInputErrors {
18
18
  [key: string]: TMessage[] | IInputErrors[];
19
19
  }
20
20
 
21
+ interface ValidatorField {
22
+ cnpj(message: string): ValidatorField;
23
+ cpf(message: string): ValidatorField;
24
+ each(
25
+ callback: <U extends Record<string, TInputValue>>(
26
+ item: U,
27
+ index: number,
28
+ subValidator: ReturnType<typeof createValidator<U>>
29
+ ) => void
30
+ ): ValidatorField;
31
+ email(message: string): ValidatorField;
32
+ expirationDate(message: string): ValidatorField;
33
+ fileMaxSize(maxSize: number, message: string): ValidatorField;
34
+ fileType(validTypes: string[], message: string): ValidatorField;
35
+ length(length: number, message: string): ValidatorField;
36
+ min(min: number, message: string): ValidatorField;
37
+ max(max: number, message: string): ValidatorField;
38
+ transform<U>(fn: (value: TInputValue) => U): ValidatorField;
39
+ slug(message: string): ValidatorField;
40
+ sanitize(): ValidatorField;
41
+ sanitizePreservingNewlines(): ValidatorField;
42
+ sanitizeHTML(tags?: AllowedTag[]): ValidatorField;
43
+ url(message: string): ValidatorField;
44
+ uuid(message: string): ValidatorField;
45
+ oneOf(types: string[], message: string): ValidatorField;
46
+ test(
47
+ validateFn: (value: TValue, context: { field: string }) => boolean,
48
+ message: string
49
+ ): ValidatorField;
50
+ videoUrl: {
51
+ youtube(message: string): ValidatorField;
52
+ };
53
+ asNumber(message: string): ValidatorField;
54
+ asBoolean(message: string): ValidatorField;
55
+ asStringArray(message: string): ValidatorField;
56
+ }
57
+
21
58
  /**
22
59
  * Cria um validador de inputs com suporte a validações encadeadas, transformação e sanitização.
23
60
  *
@@ -128,7 +165,7 @@ export function createValidator<
128
165
  );
129
166
  };
130
167
 
131
- const validator = {
168
+ const validator: ValidatorField = {
132
169
  cnpj: (message: string) => {
133
170
  if (shouldSkipValidation()) {
134
171
  return validator;
@@ -212,6 +249,53 @@ export function createValidator<
212
249
 
213
250
  return validator;
214
251
  },
252
+ expirationDate: (message: string) => {
253
+ if (shouldSkipValidation()) {
254
+ return validator;
255
+ }
256
+
257
+ if (typeof current.value === 'string') {
258
+ const expirationDate = current.value;
259
+ const regex = /^(\d{2})\/(\d{2}|\d{4})$/;
260
+ const match = expirationDate.match(regex);
261
+ if (!match) {
262
+ current.pushError(message);
263
+
264
+ return validator;
265
+ }
266
+
267
+ const month = Number.parseInt(match[1], 10);
268
+ let year = Number.parseInt(match[2], 10);
269
+
270
+ if (month < 1 || month > 12) {
271
+ current.pushError(message);
272
+ return validator;
273
+ }
274
+
275
+ const now = new Date();
276
+ const currentYear = now.getFullYear();
277
+ const currentMonth = now.getMonth() + 1;
278
+
279
+ // Se vier YY, transforme para YYYY
280
+ if (year < 100) {
281
+ const century = Math.floor(currentYear / 100) * 100;
282
+ year += century;
283
+ if (year < currentYear) year += 100; // Evita voltar para o passado
284
+ }
285
+
286
+ if (
287
+ year < currentYear ||
288
+ (year === currentYear && month < currentMonth)
289
+ ) {
290
+ current.pushError(message);
291
+ return validator;
292
+ }
293
+ } else {
294
+ current.pushError(message);
295
+ }
296
+
297
+ return validator;
298
+ },
215
299
  fileMaxSize: (maxSize: number, message: string) => {
216
300
  if (shouldSkipValidation()) {
217
301
  return validator;