softable-pixels-web 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 +22 -0
- package/dist/TabSwitch-D6OPAUjC.js +304 -0
- package/dist/TabSwitch-D6OPAUjC.js.map +1 -0
- package/dist/ThemeContext-CRXby8a0.js +539 -0
- package/dist/ThemeContext-CRXby8a0.js.map +1 -0
- package/dist/index-CZOu4S--.d.ts +69 -0
- package/dist/index-jFi4YRO5.d.ts +277 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/mask-modules.d.ts +144 -0
- package/dist/mask-modules.js +705 -0
- package/dist/mask-modules.js.map +1 -0
- package/dist/tab-switch.d.ts +2 -0
- package/dist/tab-switch.js +3 -0
- package/dist/theme-context.d.ts +2 -0
- package/dist/theme-context.js +3 -0
- package/package.json +67 -0
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
//#region src/services/MaskModule/MaskModule.ts
|
|
2
|
+
const locales = {};
|
|
3
|
+
function ensureLocale(locale) {
|
|
4
|
+
if (!locales[locale]) locales[locale] = {
|
|
5
|
+
masks: {},
|
|
6
|
+
validators: {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const MaskModule = {
|
|
10
|
+
registerMask(locale, type, mask) {
|
|
11
|
+
ensureLocale(locale);
|
|
12
|
+
locales[locale].masks[type] = mask;
|
|
13
|
+
},
|
|
14
|
+
registerValidator(locale, type, validator) {
|
|
15
|
+
ensureLocale(locale);
|
|
16
|
+
locales[locale].validators[type] = validator;
|
|
17
|
+
},
|
|
18
|
+
getMask(locale, type) {
|
|
19
|
+
return locales[locale]?.masks[type];
|
|
20
|
+
},
|
|
21
|
+
getValidator(locale, type) {
|
|
22
|
+
return locales[locale]?.validators[type];
|
|
23
|
+
},
|
|
24
|
+
reset() {
|
|
25
|
+
Object.keys(locales).forEach((locale) => {
|
|
26
|
+
delete locales[locale];
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/services/MaskModule/enums.ts
|
|
33
|
+
/**
|
|
34
|
+
* Supported locales (country + language region).
|
|
35
|
+
*
|
|
36
|
+
* Extend this enum as needed for new countries.
|
|
37
|
+
*/
|
|
38
|
+
let Locale = /* @__PURE__ */ function(Locale$1) {
|
|
39
|
+
Locale$1["BR"] = "pt-BR";
|
|
40
|
+
Locale$1["US"] = "en-US";
|
|
41
|
+
Locale$1["AR"] = "es-AR";
|
|
42
|
+
return Locale$1;
|
|
43
|
+
}({});
|
|
44
|
+
/**
|
|
45
|
+
* Types of masks supported in the system.
|
|
46
|
+
*
|
|
47
|
+
* Add new types as needed for different data formats.
|
|
48
|
+
*/
|
|
49
|
+
let MaskType = /* @__PURE__ */ function(MaskType$1) {
|
|
50
|
+
MaskType$1["CPF"] = "CPF";
|
|
51
|
+
MaskType$1["CNPJ"] = "CNPJ";
|
|
52
|
+
MaskType$1["DOCUMENT"] = "DOCUMENT";
|
|
53
|
+
MaskType$1["PHONE"] = "PHONE";
|
|
54
|
+
MaskType$1["DATE"] = "DATE";
|
|
55
|
+
MaskType$1["FLOAT"] = "FLOAT";
|
|
56
|
+
MaskType$1["INTEGER"] = "INTEGER";
|
|
57
|
+
MaskType$1["MONEY"] = "MONEY";
|
|
58
|
+
MaskType$1["ZIP_CODE"] = "ZIP_CODE";
|
|
59
|
+
MaskType$1["NUMERIC_SYMBOL"] = "NUMERIC_SYMBOL";
|
|
60
|
+
return MaskType$1;
|
|
61
|
+
}({});
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/services/MaskModule/base/maskUtils.ts
|
|
65
|
+
/**
|
|
66
|
+
* Removes all non-numeric characters from a string.
|
|
67
|
+
* @param value - Input string.
|
|
68
|
+
* @returns String containing only digits.
|
|
69
|
+
*/
|
|
70
|
+
function onlyDigits(value) {
|
|
71
|
+
if (value == null) return "";
|
|
72
|
+
return value.replace(/\D/g, "");
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Applies the mask progressively according to the available characters.
|
|
76
|
+
*
|
|
77
|
+
* Alphanumeric characters (letters and digits) in the pattern will be replaced
|
|
78
|
+
* by characters from the input `value`, in order. Non-alphanumeric characters
|
|
79
|
+
* (e.g. `.`, `-`, `/`) are treated as static parts of the mask.
|
|
80
|
+
*
|
|
81
|
+
* Examples:
|
|
82
|
+
*
|
|
83
|
+
* applyPattern('12345', 'XXX.XXX.XXX-XX') -> '123.45'
|
|
84
|
+
*
|
|
85
|
+
* applyPattern('AB1234', 'AA-NN.NN') -> 'AB-12.34'
|
|
86
|
+
*
|
|
87
|
+
* applyPattern('12345678901', 'XXX.XXX.XXX-XX') -> '123.456.789-01'
|
|
88
|
+
*
|
|
89
|
+
* @param value - raw input string (partial or complete)
|
|
90
|
+
* @param pattern - mask pattern where alphanumeric characters are placeholders
|
|
91
|
+
* @returns partially formatted string
|
|
92
|
+
*/
|
|
93
|
+
function applyPattern(value, pattern) {
|
|
94
|
+
if (value == null) return "";
|
|
95
|
+
if (pattern == null) return value;
|
|
96
|
+
let result = "";
|
|
97
|
+
let digitIndex = 0;
|
|
98
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
99
|
+
const char = pattern[i];
|
|
100
|
+
if (/[a-zA-Z0-9]/.test(char)) if (digitIndex < value.length) result += value[digitIndex++];
|
|
101
|
+
else break;
|
|
102
|
+
else if (digitIndex < value.length) result += char;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Limits the length of a string to a maximum.
|
|
108
|
+
* @param value - Input string.
|
|
109
|
+
* @param maxLength - Maximum length allowed.
|
|
110
|
+
* @returns Truncated string if longer than maxLength.
|
|
111
|
+
*/
|
|
112
|
+
function limitLength(value, maxLength) {
|
|
113
|
+
if (value == null) return "";
|
|
114
|
+
if (maxLength === void 0) return value;
|
|
115
|
+
return value.slice(0, maxLength);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/services/MaskModule/base/BaseMask.ts
|
|
120
|
+
/**
|
|
121
|
+
* Abstract class that provides default behavior for most masks.
|
|
122
|
+
* - Implements unmask() by removing all non-numeric characters.
|
|
123
|
+
* - Supports optional maxLength and minLength constraints.
|
|
124
|
+
*/
|
|
125
|
+
var BaseMask = class {
|
|
126
|
+
/**
|
|
127
|
+
* Maximum length of the masked string (optional).
|
|
128
|
+
*/
|
|
129
|
+
maxLength;
|
|
130
|
+
/**
|
|
131
|
+
* Minimum length of the masked string (optional).
|
|
132
|
+
*/
|
|
133
|
+
minLength;
|
|
134
|
+
constructor(minLength, maxLength) {
|
|
135
|
+
this.maxLength = maxLength;
|
|
136
|
+
this.minLength = minLength;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Removes all non-numeric characters from a string.
|
|
140
|
+
* @param value - Masked or unmasked string.
|
|
141
|
+
* @returns Plain string with digits only.
|
|
142
|
+
*/
|
|
143
|
+
unmask(value) {
|
|
144
|
+
return onlyDigits(value);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/services/MaskModule/locales/br/masks/CpfMask.ts
|
|
150
|
+
const CPF_PATTERN = "XXX.XXX.XXX-XX";
|
|
151
|
+
var CpfMask = class extends BaseMask {
|
|
152
|
+
constructor() {
|
|
153
|
+
const length = 14;
|
|
154
|
+
super(length, length);
|
|
155
|
+
}
|
|
156
|
+
format(value) {
|
|
157
|
+
return limitLength(applyPattern(onlyDigits(value), CPF_PATTERN), this.maxLength);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/services/MaskModule/locales/br/masks/CnpjMask.ts
|
|
163
|
+
const CNPJ_PATTERN = "XX.XXX.XXX/XXXX-XX";
|
|
164
|
+
var CnpjMask = class extends BaseMask {
|
|
165
|
+
constructor() {
|
|
166
|
+
const length = 18;
|
|
167
|
+
super(length, length);
|
|
168
|
+
}
|
|
169
|
+
format(value) {
|
|
170
|
+
return limitLength(applyPattern(onlyDigits(value), CNPJ_PATTERN), this.maxLength);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/services/MaskModule/locales/br/masks/DateMask.ts
|
|
176
|
+
var DateMask = class extends BaseMask {
|
|
177
|
+
constructor() {
|
|
178
|
+
const length = 10;
|
|
179
|
+
super(length, length);
|
|
180
|
+
}
|
|
181
|
+
format(value) {
|
|
182
|
+
const digits = onlyDigits(value);
|
|
183
|
+
let day = digits.slice(0, 2);
|
|
184
|
+
let month = digits.slice(2, 4);
|
|
185
|
+
let year = digits.slice(4, 8);
|
|
186
|
+
if (day.length === 2) {
|
|
187
|
+
const parsed = parseInt(day);
|
|
188
|
+
if (parsed > 31) day = "31";
|
|
189
|
+
else if (parsed < 1) day = "01";
|
|
190
|
+
}
|
|
191
|
+
if (month.length === 2) {
|
|
192
|
+
const parsed = parseInt(month);
|
|
193
|
+
if (parsed > 12) month = "12";
|
|
194
|
+
else if (parsed < 1) month = "01";
|
|
195
|
+
}
|
|
196
|
+
if (year.length === 4) {
|
|
197
|
+
if (parseInt(year) < 0) year = "0000";
|
|
198
|
+
}
|
|
199
|
+
let result = "";
|
|
200
|
+
if (day) result += day;
|
|
201
|
+
if (month) result += `/${month}`;
|
|
202
|
+
if (year) result += `/${year}`;
|
|
203
|
+
return limitLength(result, this.maxLength);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/services/MaskModule/locales/br/masks/PhoneMask.ts
|
|
209
|
+
/**
|
|
210
|
+
* Formats a Brazilian phone number progressively:
|
|
211
|
+
* (XX) XXXXX-XXXX or (XX) XXXX-XXXX depending on length.
|
|
212
|
+
*/
|
|
213
|
+
var PhoneMask = class extends BaseMask {
|
|
214
|
+
constructor(maxLength = 15) {
|
|
215
|
+
super(14, maxLength);
|
|
216
|
+
}
|
|
217
|
+
format(value) {
|
|
218
|
+
const digits = limitLength(onlyDigits(value), this.maxLength);
|
|
219
|
+
if (!digits) return "";
|
|
220
|
+
if (digits.length < 3) return `(${digits}`;
|
|
221
|
+
const ddd = digits.slice(0, 2);
|
|
222
|
+
const rest = digits.slice(2);
|
|
223
|
+
if (rest.length <= 4) return `(${ddd}) ${rest}`;
|
|
224
|
+
else if (rest.length <= 8) {
|
|
225
|
+
const part1 = rest.slice(0, 4);
|
|
226
|
+
const part2 = rest.slice(4);
|
|
227
|
+
return `(${ddd}) ${part1}${part2 ? `-${part2}` : ""}`;
|
|
228
|
+
} else return `(${ddd}) ${rest.slice(0, 5)}-${rest.slice(5)}`;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/services/MaskModule/locales/br/masks/FloatMask.ts
|
|
234
|
+
/**
|
|
235
|
+
* Automatically formats a numeric input as a float using comma as decimal separator.
|
|
236
|
+
*
|
|
237
|
+
* Ignores user-entered punctuation and inserts the comma based on configured decimal places.
|
|
238
|
+
*/
|
|
239
|
+
var FloatMask = class extends BaseMask {
|
|
240
|
+
maxDecimalPlaces;
|
|
241
|
+
constructor(decimalDigits = 2, maxLength = 20) {
|
|
242
|
+
super(1, maxLength);
|
|
243
|
+
this.maxDecimalPlaces = decimalDigits;
|
|
244
|
+
}
|
|
245
|
+
format(value) {
|
|
246
|
+
const digits = limitLength(onlyDigits(value), this.maxLength);
|
|
247
|
+
if (!digits) return "";
|
|
248
|
+
const length = digits.length;
|
|
249
|
+
if (length <= this.maxDecimalPlaces) {
|
|
250
|
+
const padded = digits.padStart(this.maxDecimalPlaces + 1, "0");
|
|
251
|
+
return `${padded.slice(0, padded.length - this.maxDecimalPlaces)},${padded.slice(-this.maxDecimalPlaces)}`;
|
|
252
|
+
}
|
|
253
|
+
const intPart = digits.slice(0, length - this.maxDecimalPlaces);
|
|
254
|
+
const decimalPart = digits.slice(-this.maxDecimalPlaces);
|
|
255
|
+
return `${this.formatThousands(intPart)},${decimalPart}`;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Adds dot thousand separators to a string of digits.
|
|
259
|
+
* Example: "1234567" => "1.234.567"
|
|
260
|
+
*/
|
|
261
|
+
formatThousands(value) {
|
|
262
|
+
return value.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/services/MaskModule/locales/br/masks/MoneyMask.ts
|
|
268
|
+
/**
|
|
269
|
+
* Formats input as currency, with thousand separator, decimal comma,
|
|
270
|
+
* optional prefix (e.g. R$, $), and support for negatives.
|
|
271
|
+
*
|
|
272
|
+
* Examples:
|
|
273
|
+
* - "123456" → "R$ 1.234,56"
|
|
274
|
+
* - "-123" → "R$ -1,23"
|
|
275
|
+
*/
|
|
276
|
+
var MoneyMask = class extends BaseMask {
|
|
277
|
+
maxDecimalPlaces;
|
|
278
|
+
prefix;
|
|
279
|
+
allowNegative;
|
|
280
|
+
constructor({ prefix = "R$", maxDecimalPlaces = 2, allowNegative = true, maxLength = 20 } = {}) {
|
|
281
|
+
super(1, maxLength);
|
|
282
|
+
this.prefix = prefix;
|
|
283
|
+
this.maxDecimalPlaces = maxDecimalPlaces;
|
|
284
|
+
this.allowNegative = allowNegative;
|
|
285
|
+
}
|
|
286
|
+
format(value) {
|
|
287
|
+
if (!value) return "";
|
|
288
|
+
const isNegative = this.allowNegative && value.trim().startsWith("-");
|
|
289
|
+
const digits = onlyDigits(value).slice(0, this.maxLength);
|
|
290
|
+
if (!digits) return isNegative ? `${this.prefix} -0,${"0".repeat(this.maxDecimalPlaces)}` : `${this.prefix} 0,${"0".repeat(this.maxDecimalPlaces)}`;
|
|
291
|
+
const len = digits.length;
|
|
292
|
+
if (len <= this.maxDecimalPlaces) {
|
|
293
|
+
const padded = digits.padStart(this.maxDecimalPlaces + 1, "0");
|
|
294
|
+
const intPart = padded.slice(0, padded.length - this.maxDecimalPlaces);
|
|
295
|
+
const decimalPart = padded.slice(-this.maxDecimalPlaces);
|
|
296
|
+
return `${this.prefix} ${isNegative ? "-" : ""}${intPart},${decimalPart}`;
|
|
297
|
+
}
|
|
298
|
+
const intRaw = digits.slice(0, len - this.maxDecimalPlaces);
|
|
299
|
+
const decimal = digits.slice(-this.maxDecimalPlaces);
|
|
300
|
+
const intFormatted = this.formatThousands(intRaw);
|
|
301
|
+
return `${this.prefix} ${isNegative ? "-" : ""}${intFormatted},${decimal}`;
|
|
302
|
+
}
|
|
303
|
+
formatThousands(value) {
|
|
304
|
+
return value.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region src/services/MaskModule/locales/br/masks/IntegerMask.ts
|
|
310
|
+
/**
|
|
311
|
+
* Formats integers, allowing only digits.
|
|
312
|
+
*/
|
|
313
|
+
var IntegerMask = class extends BaseMask {
|
|
314
|
+
constructor(maxLength = 15) {
|
|
315
|
+
super(1, maxLength);
|
|
316
|
+
}
|
|
317
|
+
format(value) {
|
|
318
|
+
return limitLength(onlyDigits(value), this.maxLength);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/services/MaskModule/locales/br/masks/ZipCodeMask.ts
|
|
324
|
+
const ZIP_CODE_PATTERN = "XXXXX-XXX";
|
|
325
|
+
var ZipCodeMask = class extends BaseMask {
|
|
326
|
+
constructor() {
|
|
327
|
+
const length = 9;
|
|
328
|
+
super(length, length);
|
|
329
|
+
}
|
|
330
|
+
format(value) {
|
|
331
|
+
return limitLength(applyPattern(onlyDigits(value), ZIP_CODE_PATTERN), this.maxLength);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
//#endregion
|
|
336
|
+
//#region src/services/MaskModule/types.ts
|
|
337
|
+
/**
|
|
338
|
+
* Mode of document mask and validator.
|
|
339
|
+
*
|
|
340
|
+
* - AUTO: Automatically detect based on length.
|
|
341
|
+
* - CPF: Force CPF.
|
|
342
|
+
* - CNPJ: Force CNPJ.
|
|
343
|
+
*/
|
|
344
|
+
let DocumentMode = /* @__PURE__ */ function(DocumentMode$1) {
|
|
345
|
+
DocumentMode$1["CPF"] = "cpf";
|
|
346
|
+
DocumentMode$1["CNPJ"] = "cnpj";
|
|
347
|
+
DocumentMode$1["AUTO"] = "auto";
|
|
348
|
+
return DocumentMode$1;
|
|
349
|
+
}({});
|
|
350
|
+
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/services/MaskModule/locales/br/masks/DocumentMask.ts
|
|
353
|
+
var DocumentMask = class extends BaseMask {
|
|
354
|
+
cpfMask = new CpfMask();
|
|
355
|
+
cnpjMask = new CnpjMask();
|
|
356
|
+
mode;
|
|
357
|
+
constructor(mode = DocumentMode.AUTO) {
|
|
358
|
+
super();
|
|
359
|
+
this.mode = mode;
|
|
360
|
+
}
|
|
361
|
+
format(value) {
|
|
362
|
+
const digits = onlyDigits(value);
|
|
363
|
+
const mode = this.resolveMode(digits);
|
|
364
|
+
if (mode === DocumentMode.CPF) return this.cpfMask.format(digits);
|
|
365
|
+
if (mode === DocumentMode.CNPJ) return this.cnpjMask.format(digits);
|
|
366
|
+
return digits;
|
|
367
|
+
}
|
|
368
|
+
resolveMode(digits) {
|
|
369
|
+
if (this.mode === DocumentMode.CPF) return DocumentMode.CPF;
|
|
370
|
+
if (this.mode === DocumentMode.CNPJ) return DocumentMode.CNPJ;
|
|
371
|
+
return digits.length <= 11 ? DocumentMode.CPF : DocumentMode.CNPJ;
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/services/MaskModule/locales/br/masks/NumericSymbolMask.ts
|
|
377
|
+
var NumericSymbolMask = class extends BaseMask {
|
|
378
|
+
constructor(maxLength = 25) {
|
|
379
|
+
super(1, maxLength);
|
|
380
|
+
}
|
|
381
|
+
format(value) {
|
|
382
|
+
if (value == null) return "";
|
|
383
|
+
return limitLength(value.replace(/[^\d.,/-]/g, ""), this.maxLength);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
//#endregion
|
|
388
|
+
//#region src/services/MaskModule/base/BaseValidator.ts
|
|
389
|
+
/**
|
|
390
|
+
* Abstract class providing common validation utilities.
|
|
391
|
+
* - Supports regex validation.
|
|
392
|
+
* - Supports min and max length validation.
|
|
393
|
+
*/
|
|
394
|
+
var BaseValidator = class {
|
|
395
|
+
pattern;
|
|
396
|
+
minLength;
|
|
397
|
+
maxLength;
|
|
398
|
+
constructor(options) {
|
|
399
|
+
this.pattern = options?.pattern;
|
|
400
|
+
this.minLength = options?.minLength;
|
|
401
|
+
this.maxLength = options?.maxLength;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Validates the input value based on:
|
|
405
|
+
* - Pattern matching (if defined)
|
|
406
|
+
* - Min length (if defined)
|
|
407
|
+
* - Max length (if defined)
|
|
408
|
+
*
|
|
409
|
+
* Override this method if you need custom validation logic.
|
|
410
|
+
*
|
|
411
|
+
* @param value - Value to validate (usually masked string)
|
|
412
|
+
* @returns true if valid, false otherwise
|
|
413
|
+
*/
|
|
414
|
+
validate(value) {
|
|
415
|
+
if (value == null) return false;
|
|
416
|
+
const length = value.length;
|
|
417
|
+
if (this.minLength !== void 0 && length < this.minLength) return false;
|
|
418
|
+
if (this.maxLength !== void 0 && length > this.maxLength) return false;
|
|
419
|
+
if (this.pattern && !this.pattern.test(value)) return false;
|
|
420
|
+
return true;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region src/services/MaskModule/locales/br/validators/CpfValidator.ts
|
|
426
|
+
var CpfValidator = class extends BaseValidator {
|
|
427
|
+
constructor() {
|
|
428
|
+
const length = CPF_PATTERN.length;
|
|
429
|
+
super({
|
|
430
|
+
minLength: length,
|
|
431
|
+
maxLength: length
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
validate(value) {
|
|
435
|
+
if (value == null) return false;
|
|
436
|
+
return isCpfValid(value);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
/**
|
|
440
|
+
* Validates if a CPF (Brazilian tax ID) is valid.
|
|
441
|
+
*
|
|
442
|
+
* This function:
|
|
443
|
+
* - Removes any non-digit characters (dots, dashes, spaces).
|
|
444
|
+
* - Checks if CPF has 11 digits.
|
|
445
|
+
* - Rejects CPFs where all digits are the same (e.g., '11111111111').
|
|
446
|
+
* - Performs CPF check digit validation (standard algorithm).
|
|
447
|
+
*
|
|
448
|
+
* @param inputCPF - CPF as a string, can be formatted (e.g., "123.456.789-09").
|
|
449
|
+
* @returns true if CPF is valid, false otherwise.
|
|
450
|
+
*/
|
|
451
|
+
function isCpfValid(inputCPF) {
|
|
452
|
+
const cpfOnlyNumbers = inputCPF.replace(/[\s.-]/g, "");
|
|
453
|
+
if (cpfOnlyNumbers.length !== 11) return false;
|
|
454
|
+
if (/^(\d)\1{10}$/.test(cpfOnlyNumbers)) return false;
|
|
455
|
+
let sum = 0;
|
|
456
|
+
for (let i = 0; i < 9; i++) sum += parseInt(cpfOnlyNumbers.charAt(i)) * (10 - i);
|
|
457
|
+
let firstCheckDigit = sum * 10 % 11;
|
|
458
|
+
if (firstCheckDigit === 10 || firstCheckDigit === 11) firstCheckDigit = 0;
|
|
459
|
+
if (firstCheckDigit !== parseInt(cpfOnlyNumbers.charAt(9))) return false;
|
|
460
|
+
sum = 0;
|
|
461
|
+
for (let i = 0; i < 10; i++) sum += parseInt(cpfOnlyNumbers.charAt(i)) * (11 - i);
|
|
462
|
+
let secondCheckDigit = sum * 10 % 11;
|
|
463
|
+
if (secondCheckDigit === 10 || secondCheckDigit === 11) secondCheckDigit = 0;
|
|
464
|
+
if (secondCheckDigit !== parseInt(cpfOnlyNumbers.charAt(10))) return false;
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
//#endregion
|
|
469
|
+
//#region src/services/MaskModule/locales/br/validators/CnpjValidator.ts
|
|
470
|
+
var CnpjValidator = class extends BaseValidator {
|
|
471
|
+
constructor() {
|
|
472
|
+
const length = CNPJ_PATTERN.length;
|
|
473
|
+
super({
|
|
474
|
+
minLength: length,
|
|
475
|
+
maxLength: length
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
validate(value) {
|
|
479
|
+
if (value == null) return false;
|
|
480
|
+
return isCnpjValid(value);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
/**
|
|
484
|
+
* Validates whether a given CNPJ number is valid.
|
|
485
|
+
* @param cnpj The CNPJ number as a string.
|
|
486
|
+
* @returns True if valid, false otherwise.
|
|
487
|
+
*/
|
|
488
|
+
function isCnpjValid(cnpj) {
|
|
489
|
+
if (!cnpj) return false;
|
|
490
|
+
const cleanedCnpj = cnpj.replace(/[^\d]+/g, "");
|
|
491
|
+
if (cleanedCnpj.length !== 14) return false;
|
|
492
|
+
if (/^(\d)\1{13}$/.test(cleanedCnpj)) return false;
|
|
493
|
+
const baseCnpj = cleanedCnpj.slice(0, 12);
|
|
494
|
+
const checkDigits = cleanedCnpj.slice(12);
|
|
495
|
+
const firstCheckDigit = calculateCnpjCheckDigit(calculateCnpjWeightedSum(baseCnpj, 12, 5));
|
|
496
|
+
if (firstCheckDigit !== Number(checkDigits.charAt(0))) return false;
|
|
497
|
+
if (calculateCnpjCheckDigit(calculateCnpjWeightedSum(baseCnpj + firstCheckDigit, 13, 6)) !== Number(checkDigits.charAt(1))) return false;
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Calculates the weighted sum for CNPJ verification digits.
|
|
502
|
+
* @param numbers The numeric string of the CNPJ.
|
|
503
|
+
* @param size The number of digits to consider for the calculation.
|
|
504
|
+
* @param position The starting multiplier position (5 or 6).
|
|
505
|
+
* @returns The weighted sum.
|
|
506
|
+
*/
|
|
507
|
+
function calculateCnpjWeightedSum(numbers, size, position) {
|
|
508
|
+
let sum = 0;
|
|
509
|
+
for (let i = 0; i < size; i++) {
|
|
510
|
+
sum += Number(numbers.charAt(i)) * position;
|
|
511
|
+
position--;
|
|
512
|
+
if (position < 2) position = 9;
|
|
513
|
+
}
|
|
514
|
+
return sum;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Calculates the verification digit based on the weighted sum.
|
|
518
|
+
* @param sum The weighted sum.
|
|
519
|
+
* @returns The verification digit (0-9).
|
|
520
|
+
*/
|
|
521
|
+
function calculateCnpjCheckDigit(sum) {
|
|
522
|
+
const remainder = sum % 11;
|
|
523
|
+
return remainder < 2 ? 0 : 11 - remainder;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
//#endregion
|
|
527
|
+
//#region src/services/MaskModule/locales/br/validators/DateValidator.ts
|
|
528
|
+
/**
|
|
529
|
+
* Validator for dates in the format dd/mm/yyyy.
|
|
530
|
+
*
|
|
531
|
+
* Ensures the format is correct and the date is valid in the calendar (e.g. 30/02 is invalid).
|
|
532
|
+
*/
|
|
533
|
+
var DateValidator = class extends BaseValidator {
|
|
534
|
+
constructor() {
|
|
535
|
+
super({
|
|
536
|
+
minLength: 10,
|
|
537
|
+
maxLength: 10,
|
|
538
|
+
pattern: /^\d{2}\/\d{2}\/\d{4}$/
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
validate(value) {
|
|
542
|
+
if (!super.validate(value)) return false;
|
|
543
|
+
const [dayStr, monthStr, yearStr] = value.split("/");
|
|
544
|
+
const day = parseInt(dayStr, 10);
|
|
545
|
+
const month = parseInt(monthStr, 10);
|
|
546
|
+
const year = parseInt(yearStr, 10);
|
|
547
|
+
const date = new Date(year, month - 1, day);
|
|
548
|
+
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
//#endregion
|
|
553
|
+
//#region src/services/MaskModule/locales/br/validators/PhoneValidator.ts
|
|
554
|
+
/**
|
|
555
|
+
* Validates a Brazilian phone number with optional mobile or landline support.
|
|
556
|
+
*/
|
|
557
|
+
var PhoneValidator = class extends BaseValidator {
|
|
558
|
+
allowedDDDs;
|
|
559
|
+
constructor({ allowMobile = true, allowLandline = true, allowedDDDs = Array.from({ length: 89 }, (_, i) => `${i + 11}`), minLength, maxLength } = {}) {
|
|
560
|
+
super({
|
|
561
|
+
pattern: allowMobile && allowLandline ? /^\(?\d{2}\)?\s?(\d{4,5})-?\d{4}$/ : allowMobile ? /^\(?(\d{2})\)?\s?\d{5}-?\d{4}$/ : /^\(?(\d{2})\)?\s?\d{4}-?\d{4}$/,
|
|
562
|
+
minLength,
|
|
563
|
+
maxLength
|
|
564
|
+
});
|
|
565
|
+
this.allowedDDDs = allowedDDDs;
|
|
566
|
+
}
|
|
567
|
+
validate(value) {
|
|
568
|
+
if (!super.validate(value)) return false;
|
|
569
|
+
const digits = value.replace(/\D/g, "");
|
|
570
|
+
if (digits.length !== 10 && digits.length !== 11) return false;
|
|
571
|
+
const ddd = digits.slice(0, 2);
|
|
572
|
+
return this.allowedDDDs.includes(ddd);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
//#endregion
|
|
577
|
+
//#region src/services/MaskModule/locales/br/validators/FloatValidator.ts
|
|
578
|
+
var FloatValidator = class extends BaseValidator {
|
|
579
|
+
constructor(maxDecimalPlaces = 3, minLength = 1, maxLength = 20) {
|
|
580
|
+
const decimalRegex = /* @__PURE__ */ new RegExp(`^\\d+(,\\d{1,${maxDecimalPlaces}})?$`);
|
|
581
|
+
super({
|
|
582
|
+
pattern: decimalRegex,
|
|
583
|
+
minLength,
|
|
584
|
+
maxLength
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
//#endregion
|
|
590
|
+
//#region src/services/MaskModule/locales/br/validators/MoneyValidator.ts
|
|
591
|
+
/**
|
|
592
|
+
* Validates formatted currency strings.
|
|
593
|
+
*
|
|
594
|
+
* Supports optional prefix, negative values, and comma decimal separator.
|
|
595
|
+
*/
|
|
596
|
+
var MoneyValidator = class extends BaseValidator {
|
|
597
|
+
constructor({ prefix = "R$", maxDecimalPlaces = 2, allowNegative = true, minLength, maxLength } = {}) {
|
|
598
|
+
const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
599
|
+
const pattern = /* @__PURE__ */ new RegExp(`^${escapedPrefix}\\s?${allowNegative ? "-?" : ""}\\d{1,3}(\\.\\d{3})*(,\\d{1,${maxDecimalPlaces}})?$`);
|
|
600
|
+
super({
|
|
601
|
+
pattern,
|
|
602
|
+
minLength,
|
|
603
|
+
maxLength
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
//#endregion
|
|
609
|
+
//#region src/services/MaskModule/locales/br/validators/IntegerValidator.ts
|
|
610
|
+
var IntegerValidator = class extends BaseValidator {
|
|
611
|
+
constructor(minLength = 1, maxLength = 15) {
|
|
612
|
+
super({
|
|
613
|
+
pattern: /^\d+$/,
|
|
614
|
+
minLength,
|
|
615
|
+
maxLength
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
//#endregion
|
|
621
|
+
//#region src/services/MaskModule/locales/br/validators/ZipCodeValidator.ts
|
|
622
|
+
var ZipCodeValidator = class extends BaseValidator {
|
|
623
|
+
constructor() {
|
|
624
|
+
const length = ZIP_CODE_PATTERN.length;
|
|
625
|
+
super({
|
|
626
|
+
minLength: length,
|
|
627
|
+
maxLength: length
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
validate(value) {
|
|
631
|
+
if (value == null) return false;
|
|
632
|
+
if (this.minLength !== void 0 && value.length < this.minLength) return false;
|
|
633
|
+
if (this.maxLength !== void 0 && value.length > this.maxLength) return false;
|
|
634
|
+
return true;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
//#endregion
|
|
639
|
+
//#region src/services/MaskModule/locales/br/validators/DocumentValidator.ts
|
|
640
|
+
var DocumentValidator = class extends BaseValidator {
|
|
641
|
+
cpfValidator = new CpfValidator();
|
|
642
|
+
cnpjValidator = new CnpjValidator();
|
|
643
|
+
mode;
|
|
644
|
+
constructor(mode = DocumentMode.AUTO) {
|
|
645
|
+
super();
|
|
646
|
+
this.mode = mode;
|
|
647
|
+
}
|
|
648
|
+
validate(value) {
|
|
649
|
+
const digits = onlyDigits(value);
|
|
650
|
+
const type = this.resolveType(digits);
|
|
651
|
+
if (type === DocumentMode.CPF) return this.cpfValidator.validate(value);
|
|
652
|
+
if (type === DocumentMode.CNPJ) return this.cnpjValidator.validate(value);
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
resolveType(digits) {
|
|
656
|
+
if (this.mode === DocumentMode.CPF) return DocumentMode.CPF;
|
|
657
|
+
if (this.mode === DocumentMode.CNPJ) return DocumentMode.CNPJ;
|
|
658
|
+
return digits.length <= 11 ? DocumentMode.CPF : DocumentMode.CNPJ;
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/services/MaskModule/locales/br/validators/NumericSymbolValidator.ts
|
|
664
|
+
var NumericSymbolValidator = class extends BaseValidator {
|
|
665
|
+
constructor(minLength = 1, maxLength = 25) {
|
|
666
|
+
super({
|
|
667
|
+
pattern: /^[\d.,/-]+$/,
|
|
668
|
+
minLength,
|
|
669
|
+
maxLength
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
//#endregion
|
|
675
|
+
//#region src/services/MaskModule/locales/br/registerMasks.ts
|
|
676
|
+
function registerBrMasks() {
|
|
677
|
+
MaskModule.registerMask(Locale.BR, MaskType.CPF, new CpfMask());
|
|
678
|
+
MaskModule.registerValidator(Locale.BR, MaskType.CPF, new CpfValidator());
|
|
679
|
+
MaskModule.registerMask(Locale.BR, MaskType.CNPJ, new CnpjMask());
|
|
680
|
+
MaskModule.registerValidator(Locale.BR, MaskType.CNPJ, new CnpjValidator());
|
|
681
|
+
MaskModule.registerMask(Locale.BR, MaskType.DOCUMENT, new DocumentMask());
|
|
682
|
+
MaskModule.registerValidator(Locale.BR, MaskType.DOCUMENT, new DocumentValidator());
|
|
683
|
+
MaskModule.registerMask(Locale.BR, MaskType.PHONE, new PhoneMask());
|
|
684
|
+
MaskModule.registerValidator(Locale.BR, MaskType.PHONE, new PhoneValidator());
|
|
685
|
+
MaskModule.registerMask(Locale.BR, MaskType.DATE, new DateMask());
|
|
686
|
+
MaskModule.registerValidator(Locale.BR, MaskType.DATE, new DateValidator());
|
|
687
|
+
MaskModule.registerMask(Locale.BR, MaskType.FLOAT, new FloatMask());
|
|
688
|
+
MaskModule.registerValidator(Locale.BR, MaskType.FLOAT, new FloatValidator());
|
|
689
|
+
MaskModule.registerMask(Locale.BR, MaskType.INTEGER, new IntegerMask());
|
|
690
|
+
MaskModule.registerValidator(Locale.BR, MaskType.INTEGER, new IntegerValidator());
|
|
691
|
+
MaskModule.registerMask(Locale.BR, MaskType.MONEY, new MoneyMask());
|
|
692
|
+
MaskModule.registerValidator(Locale.BR, MaskType.MONEY, new MoneyValidator());
|
|
693
|
+
MaskModule.registerMask(Locale.BR, MaskType.NUMERIC_SYMBOL, new NumericSymbolMask());
|
|
694
|
+
MaskModule.registerValidator(Locale.BR, MaskType.NUMERIC_SYMBOL, new NumericSymbolValidator());
|
|
695
|
+
MaskModule.registerMask(Locale.BR, MaskType.ZIP_CODE, new ZipCodeMask());
|
|
696
|
+
MaskModule.registerValidator(Locale.BR, MaskType.ZIP_CODE, new ZipCodeValidator());
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
//#endregion
|
|
700
|
+
//#region src/services/MaskModule/index.ts
|
|
701
|
+
registerBrMasks();
|
|
702
|
+
|
|
703
|
+
//#endregion
|
|
704
|
+
export { Locale, MaskModule, MaskType };
|
|
705
|
+
//# sourceMappingURL=mask-modules.js.map
|