@easyflow/javascript-sdk 2.1.8 → 2.1.9

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 (94) hide show
  1. package/README.md +71 -7
  2. package/dist/index.d.ts +421 -0
  3. package/package.json +19 -6
  4. package/.babelrc +0 -5
  5. package/.github/workflows/deploy-sdk-cf.yml +0 -49
  6. package/.github/workflows/release-sdk-cdn.yml +0 -144
  7. package/.github/workflows/release-sdk.yml +0 -112
  8. package/.prettierrc +0 -6
  9. package/CDN-DEPLOYMENT.md +0 -175
  10. package/DEMO.md +0 -258
  11. package/DEPLOYMENT.md +0 -224
  12. package/INTEGRATION-GUIDE.md +0 -521
  13. package/coverage/base.css +0 -224
  14. package/coverage/block-navigation.js +0 -87
  15. package/coverage/easyflow-javascript-sdk/index.html +0 -116
  16. package/coverage/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  17. package/coverage/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  18. package/coverage/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  19. package/coverage/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  20. package/coverage/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  21. package/coverage/easyflow-javascript-sdk/libs/index.html +0 -266
  22. package/coverage/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  23. package/coverage/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  24. package/coverage/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  25. package/coverage/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  26. package/coverage/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  27. package/coverage/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  28. package/coverage/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +0 -131
  31. package/coverage/lcov-report/base.css +0 -224
  32. package/coverage/lcov-report/block-navigation.js +0 -87
  33. package/coverage/lcov-report/easyflow-javascript-sdk/index.html +0 -116
  34. package/coverage/lcov-report/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  35. package/coverage/lcov-report/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  36. package/coverage/lcov-report/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  37. package/coverage/lcov-report/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  38. package/coverage/lcov-report/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  39. package/coverage/lcov-report/easyflow-javascript-sdk/libs/index.html +0 -266
  40. package/coverage/lcov-report/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  41. package/coverage/lcov-report/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  42. package/coverage/lcov-report/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  43. package/coverage/lcov-report/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  44. package/coverage/lcov-report/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  45. package/coverage/lcov-report/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  46. package/coverage/lcov-report/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  47. package/coverage/lcov-report/favicon.png +0 -0
  48. package/coverage/lcov-report/index.html +0 -131
  49. package/coverage/lcov-report/prettify.css +0 -1
  50. package/coverage/lcov-report/prettify.js +0 -2
  51. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  52. package/coverage/lcov-report/sorter.js +0 -196
  53. package/coverage/lcov.info +0 -1429
  54. package/coverage/prettify.css +0 -1
  55. package/coverage/prettify.js +0 -2
  56. package/coverage/sort-arrow-sprite.png +0 -0
  57. package/coverage/sorter.js +0 -196
  58. package/dist/435.easyflow-sdk.min.js +0 -1
  59. package/dist/easyflow-sdk.min.js +0 -1
  60. package/dist/easyflow-sdk.min.js.LICENSE.txt +0 -1
  61. package/dist/index.html +0 -756
  62. package/docs/index.html +0 -775
  63. package/examples/lovable-integration.html +0 -410
  64. package/index.html +0 -981
  65. package/jest.config.js +0 -37
  66. package/jsdoc.json +0 -42
  67. package/libs/auto-integration.mjs +0 -333
  68. package/libs/constants.mjs +0 -61
  69. package/libs/constants.spec.js +0 -198
  70. package/libs/errors.mjs +0 -62
  71. package/libs/errors.spec.js +0 -178
  72. package/libs/exception-handler.mjs +0 -21
  73. package/libs/exception-handler.spec.js +0 -237
  74. package/libs/fingerprint.mjs +0 -270
  75. package/libs/http.mjs +0 -163
  76. package/libs/http.spec.js +0 -427
  77. package/libs/integration-wrapper.mjs +0 -285
  78. package/libs/logger.mjs +0 -161
  79. package/libs/logger.spec.js +0 -389
  80. package/libs/sanitizer.mjs +0 -340
  81. package/libs/sanitizer.spec.js +0 -583
  82. package/libs/security.mjs +0 -217
  83. package/libs/types.mjs +0 -141
  84. package/libs/utils.mjs +0 -368
  85. package/libs/utils.spec.js +0 -231
  86. package/libs/validator.mjs +0 -952
  87. package/libs/validator.spec.js +0 -615
  88. package/mocks/offer.mock.js +0 -77
  89. package/scripts/publish-npm.sh +0 -82
  90. package/sdk.mjs +0 -945
  91. package/sdk.spec.js +0 -796
  92. package/test-setup.cjs +0 -211
  93. package/test.html +0 -154
  94. package/webpack.config.cjs +0 -41
@@ -1,952 +0,0 @@
1
- import { EasyflowError, ERROR_CODES, ValidationError } from './errors.mjs'
2
- import { PAYMENT_METHODS } from './constants.mjs'
3
- import { throwsError } from './exception-handler.mjs'
4
- import { SECURITY_CONFIG } from './security.mjs'
5
-
6
- /**
7
- * Validation utilities for Easyflow SDK
8
- */
9
- export class Validator {
10
- /**
11
- * Validates if a value is a non-empty string
12
- * @param {*} value - Value to validate
13
- * @param {string} fieldName - Field name for error message
14
- * @returns {boolean} True if valid
15
- * @throws {EasyflowError} If validation fails
16
- */
17
- static isString(value, fieldName) {
18
- if (!value || typeof value !== 'string') {
19
- throwsError(
20
- new EasyflowError(
21
- `${fieldName} must be a non-empty string`,
22
- 400,
23
- ERROR_CODES.VALIDATION_ERROR
24
- )
25
- )
26
- }
27
- return true
28
- }
29
-
30
- /**
31
- * Validates if a value is a valid object
32
- * @param {*} value - Value to validate
33
- * @param {string} fieldName - Field name for error message
34
- * @returns {boolean} True if valid
35
- * @throws {EasyflowError} If validation fails
36
- */
37
- static isObject(value, fieldName) {
38
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
39
- throwsError(
40
- new EasyflowError(
41
- `${fieldName} must be a valid object`,
42
- 400,
43
- ERROR_CODES.VALIDATION_ERROR
44
- )
45
- )
46
- }
47
- return true
48
- }
49
-
50
- /**
51
- * Validates if a value is a non-empty array
52
- * @param {*} value - Value to validate
53
- * @param {string} fieldName - Field name for error message
54
- * @returns {boolean} True if valid
55
- * @throws {EasyflowError} If validation fails
56
- */
57
- static isArray(value, fieldName) {
58
- if (!Array.isArray(value) || value.length === 0) {
59
- throwsError(
60
- new EasyflowError(
61
- `${fieldName} must be a non-empty array`,
62
- 400,
63
- ERROR_CODES.VALIDATION_ERROR
64
- )
65
- )
66
- }
67
- return true
68
- }
69
-
70
- /**
71
- * Validates a payment method object
72
- * @param {Object} payment - Payment method to validate
73
- * @throws {EasyflowError} If validation fails
74
- */
75
- static validatePaymentMethod(payment) {
76
- Validator.isObject(payment, 'payment')
77
- Validator.isString(payment.method, 'payment.method')
78
- if (!Object.values(PAYMENT_METHODS).includes(payment.method)) {
79
- throwsError(
80
- new EasyflowError(
81
- `Invalid payment method: ${payment.method}`,
82
- 400,
83
- ERROR_CODES.INVALID_PAYMENT_METHOD
84
- )
85
- )
86
- }
87
-
88
- switch (payment.method) {
89
- case PAYMENT_METHODS.CREDIT_CARD:
90
- if (!payment.creditCard) {
91
- throwsError(
92
- new EasyflowError(
93
- 'Credit card data is required for credit-card payment method',
94
- 400,
95
- ERROR_CODES.MISSING_CREDIT_CARD_DATA
96
- )
97
- )
98
- Validator.validateCreditCardData(payment.creditCard)
99
- }
100
- break
101
- case PAYMENT_METHODS.PIX:
102
- break
103
- case PAYMENT_METHODS.BANK_BILLET:
104
- break
105
- }
106
- }
107
-
108
- /**
109
- * Validates credit card data
110
- * @param {Object} creditCard - Credit card data to validate
111
- * @throws {EasyflowError} If validation fails
112
- */
113
- static validateCreditCardData(creditCard) {
114
- Validator.isObject(creditCard, 'creditCard')
115
- const requiredFields = [
116
- 'cardNumber',
117
- 'holderName',
118
- 'month',
119
- 'year',
120
- 'cvv',
121
- ]
122
- requiredFields.forEach((field) => {
123
- Validator.isString(creditCard[field], `creditCard.${field}`)
124
- })
125
- if (!/^\d{13,19}$/.test(creditCard.cardNumber))
126
- throw new ValidationError('Invalid card number')
127
-
128
- if (!/^\d{3,4}$/.test(creditCard.cvv))
129
- throw new ValidationError('Invalid CVV')
130
- if (
131
- !/^\d{1,2}$/.test(creditCard.month) ||
132
- parseInt(creditCard.month) < 1 ||
133
- parseInt(creditCard.month) > 12
134
- )
135
- throw new ValidationError('Invalid expiration month')
136
- if (!/^\d{4}$/.test(creditCard.year))
137
- throw new ValidationError('Invalid expiration year')
138
- if (!creditCard.holderName || creditCard.holderName.length < 2)
139
- throw new ValidationError('Invalid holder name')
140
- }
141
-
142
- /**
143
- * Validates order data
144
- * @param {Object} data - Order data to validate
145
- * @throws {EasyflowError} If validation fails
146
- */
147
- static validateOrderData(data) {
148
- Validator.isObject(data, 'data')
149
- Validator.isArray(data.payments, 'data.payments')
150
- data.payments.forEach((payment, index) => {
151
- try {
152
- Validator.validatePaymentMethod(payment)
153
- Validator.isBiggerThanZero(
154
- payment.numberInstallments,
155
- 'numberInstallments'
156
- )
157
- } catch (error) {
158
- throwsError(
159
- new EasyflowError(
160
- `Invalid payment at index ${index}: ${error.message}`,
161
- error.status,
162
- error.code
163
- )
164
- )
165
- }
166
- })
167
- }
168
-
169
- /**
170
- * Validates if value is a valid number
171
- * @param {Number} value - Number value to validate
172
- * @param {String} fieldName - Field name for error message
173
- * @throws {EasyflowError} If validation fails
174
- */
175
- static isNumber(value, fieldName) {
176
- if (typeof value !== 'number' || isNaN(value)) {
177
- throwsError(
178
- new EasyflowError(
179
- `${fieldName} must be a valid number`,
180
- 400,
181
- ERROR_CODES.VALIDATION_ERROR
182
- )
183
- )
184
- }
185
- return true
186
- }
187
-
188
- /**
189
- * Validates if a number is greater than zero
190
- * @param {Number} value - Number value to validate
191
- * @param {String} fieldName - Field name for error message
192
- * @throws {EasyflowError} If validation fails
193
- */
194
- static isBiggerThanZero(value, fieldName) {
195
- if (!Validator.isNumber(value, fieldName) || value <= 0) {
196
- throwsError(
197
- new EasyflowError(
198
- `${fieldName} must be a number greater than zero`,
199
- 400,
200
- ERROR_CODES.VALIDATION_ERROR
201
- )
202
- )
203
- }
204
- return true
205
- }
206
-
207
- /**
208
- * Validates a URL
209
- * @param url - URL to validate
210
- * @returns {string} Validated URL
211
- * @throws {ValidationError} If validation fails
212
- */
213
- static validateUrl(url) {
214
- try {
215
- const parsed = new URL(url)
216
- if (!SECURITY_CONFIG.ALLOWED_DOMAINS.includes(parsed.hostname))
217
- throwsError(new ValidationError('Invalid domain'))
218
- if (parsed.protocol !== 'https:')
219
- throwsError(new ValidationError('HTTPS required'))
220
- return parsed.toString()
221
- } catch (error) {
222
- throwsError(new ValidationError('Invalid URL'))
223
- }
224
- }
225
-
226
- /**
227
- * Validates charge items data
228
- * @param {Object} items - Charge Items Data to validate
229
- * @throws {EasyflowError} If validation fails
230
- */
231
- static validateChargeItemsData(items) {
232
- Validator.isArray(items, 'items')
233
- items.forEach((record, index) => {
234
- try {
235
- Validator.isObject(record, `items[${index}]`)
236
- if (record.name) Validator.isString(record.name, 'name')
237
- if (record.description)
238
- Validator.isString(record.description, 'description')
239
- if (record.quantity)
240
- Validator.isBiggerThanZero(record.quantity, 'quantity')
241
- if (record.priceInCents)
242
- Validator.isNumber(record.priceInCents, 'priceInCents')
243
- } catch (error) {
244
- throwsError(
245
- new EasyflowError(
246
- `Invalid items at index ${index}: ${error.message}`,
247
- error.status,
248
- error.code
249
- )
250
- )
251
- }
252
- })
253
- }
254
-
255
- /**
256
- * Validates email format
257
- * @param {string} email - Email to validate
258
- * @param {string} fieldName - Field name for error message
259
- * @returns {boolean} True if valid
260
- * @throws {EasyflowError} If validation fails
261
- */
262
- static validateEmail(email, fieldName = 'email') {
263
- Validator.isString(email, fieldName)
264
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
265
- if (!emailRegex.test(email)) {
266
- throwsError(
267
- new EasyflowError(
268
- `${fieldName} must be a valid email address`,
269
- 400,
270
- ERROR_CODES.VALIDATION_ERROR
271
- )
272
- )
273
- }
274
-
275
- if (email.length > 254) {
276
- throwsError(
277
- new EasyflowError(
278
- `${fieldName} is too long (max 254 characters)`,
279
- 400,
280
- ERROR_CODES.VALIDATION_ERROR
281
- )
282
- )
283
- }
284
-
285
- if (
286
- email.includes('..') ||
287
- email.startsWith('.') ||
288
- email.endsWith('.')
289
- ) {
290
- throwsError(
291
- new EasyflowError(
292
- `${fieldName} contains invalid characters`,
293
- 400,
294
- ERROR_CODES.VALIDATION_ERROR
295
- )
296
- )
297
- }
298
-
299
- return true
300
- }
301
-
302
- /**
303
- * Validates CPF (Brazilian individual taxpayer number)
304
- * @param {string} cpf - CPF to validate
305
- * @param {string} fieldName - Field name for error message
306
- * @returns {boolean} True if valid
307
- * @throws {EasyflowError} If validation fails
308
- */
309
- static validateCPF(cpf, fieldName = 'CPF') {
310
- Validator.isString(cpf, fieldName)
311
-
312
- const cleanCpf = cpf.replace(/\D/g, '')
313
-
314
- if (cleanCpf.length !== 11) {
315
- throwsError(
316
- new EasyflowError(
317
- `${fieldName} must have exactly 11 digits`,
318
- 400,
319
- ERROR_CODES.VALIDATION_ERROR
320
- )
321
- )
322
- }
323
-
324
- if (/^(\d)\1{10}$/.test(cleanCpf)) {
325
- throwsError(
326
- new EasyflowError(
327
- `${fieldName} is invalid (all digits are the same)`,
328
- 400,
329
- ERROR_CODES.VALIDATION_ERROR
330
- )
331
- )
332
- }
333
-
334
- let sum = 0
335
- for (let i = 0; i < 9; i++) {
336
- sum += parseInt(cleanCpf.charAt(i)) * (10 - i)
337
- }
338
- let remainder = (sum * 10) % 11
339
- if (remainder === 10 || remainder === 11) remainder = 0
340
- if (remainder !== parseInt(cleanCpf.charAt(9))) {
341
- throwsError(
342
- new EasyflowError(
343
- `${fieldName} is invalid`,
344
- 400,
345
- ERROR_CODES.VALIDATION_ERROR
346
- )
347
- )
348
- }
349
-
350
- sum = 0
351
- for (let i = 0; i < 10; i++) {
352
- sum += parseInt(cleanCpf.charAt(i)) * (11 - i)
353
- }
354
- remainder = (sum * 10) % 11
355
- if (remainder === 10 || remainder === 11) remainder = 0
356
- if (remainder !== parseInt(cleanCpf.charAt(10))) {
357
- throwsError(
358
- new EasyflowError(
359
- `${fieldName} is invalid`,
360
- 400,
361
- ERROR_CODES.VALIDATION_ERROR
362
- )
363
- )
364
- }
365
-
366
- return true
367
- }
368
-
369
- /**
370
- * Validates CNPJ (Brazilian company taxpayer number)
371
- * @param {string} cnpj - CNPJ to validate
372
- * @param {string} fieldName - Field name for error message
373
- * @returns {boolean} True if valid
374
- * @throws {EasyflowError} If validation fails
375
- */
376
- static validateCNPJ(cnpj, fieldName = 'CNPJ') {
377
- Validator.isString(cnpj, fieldName)
378
-
379
- const cleanCnpj = cnpj.replace(/\D/g, '')
380
-
381
- if (cleanCnpj.length !== 14) {
382
- throwsError(
383
- new EasyflowError(
384
- `${fieldName} must have exactly 14 digits`,
385
- 400,
386
- ERROR_CODES.VALIDATION_ERROR
387
- )
388
- )
389
- }
390
-
391
- if (/^(\d)\1{13}$/.test(cleanCnpj)) {
392
- throwsError(
393
- new EasyflowError(
394
- `${fieldName} is invalid (all digits are the same)`,
395
- 400,
396
- ERROR_CODES.VALIDATION_ERROR
397
- )
398
- )
399
- }
400
-
401
- const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
402
- const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
403
-
404
- let sum = 0
405
- for (let i = 0; i < 12; i++) {
406
- sum += parseInt(cleanCnpj.charAt(i)) * weights1[i]
407
- }
408
- let remainder = sum % 11
409
- let digit1 = remainder < 2 ? 0 : 11 - remainder
410
-
411
- if (digit1 !== parseInt(cleanCnpj.charAt(12))) {
412
- throwsError(
413
- new EasyflowError(
414
- `${fieldName} is invalid`,
415
- 400,
416
- ERROR_CODES.VALIDATION_ERROR
417
- )
418
- )
419
- }
420
-
421
- sum = 0
422
- for (let i = 0; i < 13; i++) {
423
- sum += parseInt(cleanCnpj.charAt(i)) * weights2[i]
424
- }
425
- remainder = sum % 11
426
- let digit2 = remainder < 2 ? 0 : 11 - remainder
427
-
428
- if (digit2 !== parseInt(cleanCnpj.charAt(13))) {
429
- throwsError(
430
- new EasyflowError(
431
- `${fieldName} is invalid`,
432
- 400,
433
- ERROR_CODES.VALIDATION_ERROR
434
- )
435
- )
436
- }
437
-
438
- return true
439
- }
440
-
441
- /**
442
- * Validates legal document (CPF or CNPJ)
443
- * @param {Object} document - Document object to validate
444
- * @param {string} fieldName - Field name for error message
445
- * @returns {boolean} True if valid
446
- * @throws {EasyflowError} If validation fails
447
- */
448
- static validateLegalDocument(document, fieldName = 'document') {
449
- Validator.isObject(document, fieldName)
450
- Validator.isString(document.type, `${fieldName}.type`)
451
- Validator.isString(document.number, `${fieldName}.number`)
452
-
453
- if (!['CPF', 'CNPJ'].includes(document.type)) {
454
- throwsError(
455
- new EasyflowError(
456
- `${fieldName}.type must be either 'CPF' or 'CNPJ'`,
457
- 400,
458
- ERROR_CODES.VALIDATION_ERROR
459
- )
460
- )
461
- }
462
-
463
- if (!/^\d+$/.test(document.number)) {
464
- throwsError(
465
- new EasyflowError(
466
- `${fieldName}.number must contain only digits`,
467
- 400,
468
- ERROR_CODES.VALIDATION_ERROR
469
- )
470
- )
471
- }
472
-
473
- if (document.type === 'CPF') {
474
- Validator.validateCPF(document.number, `${fieldName}.number`)
475
- } else {
476
- Validator.validateCNPJ(document.number, `${fieldName}.number`)
477
- }
478
-
479
- return true
480
- }
481
-
482
- /**
483
- * Validates phone number
484
- * @param {Object} phone - Phone object to validate
485
- * @param {string} fieldName - Field name for error message
486
- * @returns {boolean} True if valid
487
- * @throws {EasyflowError} If validation fails
488
- */
489
- static validatePhone(phone, fieldName = 'phone') {
490
- Validator.isObject(phone, fieldName)
491
- Validator.isString(phone.areaCode, `${fieldName}.areaCode`)
492
- Validator.isString(phone.ddd, `${fieldName}.ddd`)
493
- Validator.isString(phone.number, `${fieldName}.number`)
494
-
495
- if (!/^\+\d{1,4}$/.test(phone.areaCode)) {
496
- throwsError(
497
- new EasyflowError(
498
- `${fieldName}.areaCode must be in format +XX or +XXX`,
499
- 400,
500
- ERROR_CODES.VALIDATION_ERROR
501
- )
502
- )
503
- }
504
-
505
- if (!/^\d{2}$/.test(phone.ddd)) {
506
- throwsError(
507
- new EasyflowError(
508
- `${fieldName}.ddd must be exactly 2 digits`,
509
- 400,
510
- ERROR_CODES.VALIDATION_ERROR
511
- )
512
- )
513
- }
514
-
515
- if (!/^\d{8,9}$/.test(phone.number)) {
516
- throwsError(
517
- new EasyflowError(
518
- `${fieldName}.number must be 8 or 9 digits`,
519
- 400,
520
- ERROR_CODES.VALIDATION_ERROR
521
- )
522
- )
523
- }
524
-
525
- if (typeof phone.isMobile !== 'boolean') {
526
- throwsError(
527
- new EasyflowError(
528
- `${fieldName}.isMobile must be a boolean`,
529
- 400,
530
- ERROR_CODES.VALIDATION_ERROR
531
- )
532
- )
533
- }
534
-
535
- return true
536
- }
537
-
538
- /**
539
- * Validates address
540
- * @param {Object} address - Address object to validate
541
- * @param {string} fieldName - Field name for error message
542
- * @returns {boolean} True if valid
543
- * @throws {EasyflowError} If validation fails
544
- */
545
- static validateAddress(address, fieldName = 'address') {
546
- Validator.isObject(address, fieldName)
547
-
548
- const requiredFields = [
549
- 'zipCode',
550
- 'street',
551
- 'neighborhood',
552
- 'city',
553
- 'state',
554
- 'number',
555
- ]
556
- requiredFields.forEach((field) => {
557
- Validator.isString(address[field], `${fieldName}.${field}`)
558
- })
559
-
560
- if (address.complement) {
561
- Validator.isString(address.complement, `${fieldName}.complement`)
562
- }
563
-
564
- if (!/^\d{8}$/.test(address.zipCode)) {
565
- throwsError(
566
- new EasyflowError(
567
- `${fieldName}.zipCode must be exactly 8 digits`,
568
- 400,
569
- ERROR_CODES.VALIDATION_ERROR
570
- )
571
- )
572
- }
573
-
574
- if (address.street.length < 3 || address.street.length > 100) {
575
- throwsError(
576
- new EasyflowError(
577
- `${fieldName}.street must be between 3 and 100 characters`,
578
- 400,
579
- ERROR_CODES.VALIDATION_ERROR
580
- )
581
- )
582
- }
583
-
584
- if (
585
- address.neighborhood.length < 2 ||
586
- address.neighborhood.length > 50
587
- ) {
588
- throwsError(
589
- new EasyflowError(
590
- `${fieldName}.neighborhood must be between 2 and 50 characters`,
591
- 400,
592
- ERROR_CODES.VALIDATION_ERROR
593
- )
594
- )
595
- }
596
-
597
- if (address.city.length < 2 || address.city.length > 50) {
598
- throwsError(
599
- new EasyflowError(
600
- `${fieldName}.city must be between 2 and 50 characters`,
601
- 400,
602
- ERROR_CODES.VALIDATION_ERROR
603
- )
604
- )
605
- }
606
-
607
- const validStates = [
608
- 'AC',
609
- 'AL',
610
- 'AP',
611
- 'AM',
612
- 'BA',
613
- 'CE',
614
- 'DF',
615
- 'ES',
616
- 'GO',
617
- 'MA',
618
- 'MT',
619
- 'MS',
620
- 'MG',
621
- 'PA',
622
- 'PB',
623
- 'PR',
624
- 'PE',
625
- 'PI',
626
- 'RJ',
627
- 'RN',
628
- 'RS',
629
- 'RO',
630
- 'RR',
631
- 'SC',
632
- 'SP',
633
- 'SE',
634
- 'TO',
635
- ]
636
- if (!validStates.includes(address.state.toUpperCase())) {
637
- throwsError(
638
- new EasyflowError(
639
- `${fieldName}.state must be a valid Brazilian state abbreviation`,
640
- 400,
641
- ERROR_CODES.VALIDATION_ERROR
642
- )
643
- )
644
- }
645
-
646
- if (!/^\d+[A-Za-z]?$/.test(address.number)) {
647
- throwsError(
648
- new EasyflowError(
649
- `${fieldName}.number must be a valid street number`,
650
- 400,
651
- ERROR_CODES.VALIDATION_ERROR
652
- )
653
- )
654
- }
655
-
656
- return true
657
- }
658
-
659
- /**
660
- * Validates customer data
661
- * @param {Object} customer - Customer object to validate
662
- * @param {string} fieldName - Field name for error message
663
- * @returns {boolean} True if valid
664
- * @throws {EasyflowError} If validation fails
665
- */
666
- static validateCustomer(customer, fieldName = 'customer') {
667
- Validator.isObject(customer, fieldName)
668
- Validator.isString(customer.name, `${fieldName}.name`)
669
- Validator.validateEmail(customer.email, `${fieldName}.email`)
670
- Validator.validateLegalDocument(
671
- customer.document,
672
- `${fieldName}.document`
673
- )
674
- Validator.validatePhone(customer.phone, `${fieldName}.phone`)
675
-
676
- if (customer.name.length < 2 || customer.name.length > 100) {
677
- throwsError(
678
- new EasyflowError(
679
- `${fieldName}.name must be between 2 and 100 characters`,
680
- 400,
681
- ERROR_CODES.VALIDATION_ERROR
682
- )
683
- )
684
- }
685
-
686
- if (customer.address) {
687
- Validator.validateAddress(customer.address, `${fieldName}.address`)
688
- }
689
-
690
- if (customer.deliveryAddress) {
691
- Validator.validateAddress(
692
- customer.deliveryAddress,
693
- `${fieldName}.deliveryAddress`
694
- )
695
- }
696
-
697
- return true
698
- }
699
-
700
- /**
701
- * Validates pagination parameters
702
- * @param {number} page - Page number
703
- * @param {number} limit - Items per page
704
- * @param {string} fieldName - Field name for error message
705
- * @returns {boolean} True if valid
706
- * @throws {EasyflowError} If validation fails
707
- */
708
- static validatePagination(page, limit, fieldName = 'pagination') {
709
- Validator.isNumber(page, `${fieldName}.page`)
710
- Validator.isNumber(limit, `${fieldName}.limit`)
711
-
712
- if (page < 1) {
713
- throwsError(
714
- new EasyflowError(
715
- `${fieldName}.page must be greater than 0`,
716
- 400,
717
- ERROR_CODES.VALIDATION_ERROR
718
- )
719
- )
720
- }
721
-
722
- if (limit < 1 || limit > 100) {
723
- throwsError(
724
- new EasyflowError(
725
- `${fieldName}.limit must be between 1 and 100`,
726
- 400,
727
- ERROR_CODES.VALIDATION_ERROR
728
- )
729
- )
730
- }
731
-
732
- return true
733
- }
734
-
735
- /**
736
- * Validates business ID format
737
- * @param {string} businessId - Business ID to validate
738
- * @param {string} fieldName - Field name for error message
739
- * @returns {boolean} True if valid
740
- * @throws {EasyflowError} If validation fails
741
- */
742
- static validateBusinessId(businessId, fieldName = 'businessId') {
743
- Validator.isString(businessId, fieldName)
744
-
745
- if (!/^[a-zA-Z0-9-]{3,50}$/.test(businessId)) {
746
- throwsError(
747
- new EasyflowError(
748
- `${fieldName} must be 3-50 characters long and contain only letters, numbers, and hyphens`,
749
- 400,
750
- ERROR_CODES.VALIDATION_ERROR
751
- )
752
- )
753
- }
754
-
755
- if (businessId.startsWith('-') || businessId.endsWith('-')) {
756
- throwsError(
757
- new EasyflowError(
758
- `${fieldName} cannot start or end with a hyphen`,
759
- 400,
760
- ERROR_CODES.VALIDATION_ERROR
761
- )
762
- )
763
- }
764
-
765
- if (businessId.includes('--')) {
766
- throwsError(
767
- new EasyflowError(
768
- `${fieldName} cannot contain consecutive hyphens`,
769
- 400,
770
- ERROR_CODES.VALIDATION_ERROR
771
- )
772
- )
773
- }
774
-
775
- return true
776
- }
777
-
778
- /**
779
- * Validates credit card token
780
- * @param {string} token - Credit card token to validate
781
- * @param {string} fieldName - Field name for error message
782
- * @returns {boolean} True if valid
783
- * @throws {EasyflowError} If validation fails
784
- */
785
- static validateCreditCardToken(token, fieldName = 'creditCardToken') {
786
- Validator.isString(token, fieldName)
787
-
788
- if (!/^[a-zA-Z0-9_-]{32,128}$/.test(token)) {
789
- throwsError(
790
- new EasyflowError(
791
- `${fieldName} must be a valid secure token (32-128 characters, alphanumeric, underscore, hyphen)`,
792
- 400,
793
- ERROR_CODES.VALIDATION_ERROR
794
- )
795
- )
796
- }
797
-
798
- return true
799
- }
800
-
801
- /**
802
- * Validates order ID format (UUID v4, UUID v7, or MongoDB ObjectId)
803
- * @param {string} orderId - Order ID to validate
804
- * @param {string} fieldName - Field name for error message
805
- * @returns {boolean} True if valid
806
- * @throws {EasyflowError} If validation fails
807
- */
808
- static validateOrderId(orderId, fieldName = 'orderId') {
809
- Validator.isString(orderId, fieldName)
810
-
811
- // UUID v4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
812
- const uuidV4Pattern =
813
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
814
-
815
- // UUID v7: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
816
- const uuidV7Pattern =
817
- /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
818
-
819
- // MongoDB ObjectId: 24 hex characters
820
- const mongoIdPattern = /^[0-9a-f]{24}$/i
821
-
822
- if (
823
- uuidV4Pattern.test(orderId) ||
824
- uuidV7Pattern.test(orderId) ||
825
- mongoIdPattern.test(orderId)
826
- ) {
827
- return true
828
- }
829
-
830
- throwsError(
831
- new EasyflowError(
832
- `${fieldName} must be a valid UUID v4, UUID v7, or MongoDB ObjectId`,
833
- 400,
834
- ERROR_CODES.VALIDATION_ERROR
835
- )
836
- )
837
- }
838
-
839
- /**
840
- * Validates offer ID format (UUID v4, UUID v7, or MongoDB ObjectId)
841
- * @param {string} offerId - Offer ID to validate
842
- * @param {string} fieldName - Field name for error message
843
- * @returns {boolean} True if valid
844
- * @throws {EasyflowError} If validation fails
845
- */
846
- static validateOfferId(offerId, fieldName = 'offerId') {
847
- Validator.isString(offerId, fieldName)
848
-
849
- // UUID v4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
850
- const uuidV4Pattern =
851
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
852
-
853
- // UUID v7: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
854
- const uuidV7Pattern =
855
- /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
856
-
857
- // MongoDB ObjectId: 24 hex characters
858
- const mongoIdPattern = /^[0-9a-f]{24}$/i
859
-
860
- if (
861
- uuidV4Pattern.test(offerId) ||
862
- uuidV7Pattern.test(offerId) ||
863
- mongoIdPattern.test(offerId)
864
- ) {
865
- return true
866
- }
867
-
868
- throwsError(
869
- new EasyflowError(
870
- `${fieldName} must be a valid UUID v4, UUID v7, or MongoDB ObjectId`,
871
- 400,
872
- ERROR_CODES.VALIDATION_ERROR
873
- )
874
- )
875
- }
876
-
877
- /**
878
- * Validates customer ID format (UUID v4, UUID v7, or MongoDB ObjectId)
879
- * @param {string} customerId - Customer ID to validate
880
- * @param {string} fieldName - Field name for error message
881
- * @returns {boolean} True if valid
882
- * @throws {EasyflowError} If validation fails
883
- */
884
- static validateCustomerId(customerId, fieldName = 'customerId') {
885
- Validator.isString(customerId, fieldName)
886
-
887
- // UUID v4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
888
- const uuidV4Pattern =
889
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
890
-
891
- // UUID v7: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
892
- const uuidV7Pattern =
893
- /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
894
-
895
- // MongoDB ObjectId: 24 hex characters
896
- const mongoIdPattern = /^[0-9a-f]{24}$/i
897
-
898
- if (
899
- uuidV4Pattern.test(customerId) ||
900
- uuidV7Pattern.test(customerId) ||
901
- mongoIdPattern.test(customerId)
902
- ) {
903
- return true
904
- }
905
-
906
- throwsError(
907
- new EasyflowError(
908
- `${fieldName} must be a valid UUID v4, UUID v7, or MongoDB ObjectId`,
909
- 400,
910
- ERROR_CODES.VALIDATION_ERROR
911
- )
912
- )
913
- }
914
-
915
- /**
916
- * Validates credit card ID format (UUID v4, UUID v7, or MongoDB ObjectId)
917
- * @param {string} creditCardId - Credit card ID to validate
918
- * @param {string} fieldName - Field name for error message
919
- * @returns {boolean} True if valid
920
- * @throws {EasyflowError} If validation fails
921
- */
922
- static validateCreditCardId(creditCardId, fieldName = 'creditCardId') {
923
- Validator.isString(creditCardId, fieldName)
924
-
925
- // UUID v4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
926
- const uuidV4Pattern =
927
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
928
-
929
- // UUID v7: xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx (y = 8,9,A,B)
930
- const uuidV7Pattern =
931
- /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
932
-
933
- // MongoDB ObjectId: 24 hex characters
934
- const mongoIdPattern = /^[0-9a-f]{24}$/i
935
-
936
- if (
937
- uuidV4Pattern.test(creditCardId) ||
938
- uuidV7Pattern.test(creditCardId) ||
939
- mongoIdPattern.test(creditCardId)
940
- ) {
941
- return true
942
- }
943
-
944
- throwsError(
945
- new EasyflowError(
946
- `${fieldName} must be a valid UUID v4, UUID v7, or MongoDB ObjectId`,
947
- 400,
948
- ERROR_CODES.VALIDATION_ERROR
949
- )
950
- )
951
- }
952
- }