@rainersoft/utils 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 +176 -0
- package/dist/date/index.d.mts +9 -0
- package/dist/date/index.d.ts +9 -0
- package/dist/date/index.js +105 -0
- package/dist/date/index.js.map +1 -0
- package/dist/date/index.mjs +99 -0
- package/dist/date/index.mjs.map +1 -0
- package/dist/index.d.mts +108 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +846 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +797 -0
- package/dist/index.mjs.map +1 -0
- package/dist/number/index.d.mts +11 -0
- package/dist/number/index.d.ts +11 -0
- package/dist/number/index.js +61 -0
- package/dist/number/index.js.map +1 -0
- package/dist/number/index.mjs +53 -0
- package/dist/number/index.mjs.map +1 -0
- package/dist/status/index.d.mts +8 -0
- package/dist/status/index.d.ts +8 -0
- package/dist/status/index.js +126 -0
- package/dist/status/index.js.map +1 -0
- package/dist/status/index.mjs +122 -0
- package/dist/status/index.mjs.map +1 -0
- package/dist/string/index.d.mts +9 -0
- package/dist/string/index.d.ts +9 -0
- package/dist/string/index.js +35 -0
- package/dist/string/index.js.map +1 -0
- package/dist/string/index.mjs +27 -0
- package/dist/string/index.mjs.map +1 -0
- package/dist/types-tUMATEGI.d.mts +10 -0
- package/dist/types-tUMATEGI.d.ts +10 -0
- package/package.json +87 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,797 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/types.ts
|
|
8
|
+
var DEFAULT_LOCALE = "pt-BR";
|
|
9
|
+
var CURRENCY_MAP = {
|
|
10
|
+
"pt-BR": "BRL",
|
|
11
|
+
"en-US": "USD",
|
|
12
|
+
"es-ES": "EUR"
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// src/text/index.ts
|
|
16
|
+
function extractInitials(name, maxChars = 2) {
|
|
17
|
+
if (!name || !name.trim()) {
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
|
+
const words = name.trim().split(/\s+/);
|
|
21
|
+
const initials = words.slice(0, maxChars).map((word) => word.charAt(0).toUpperCase()).join("");
|
|
22
|
+
return initials;
|
|
23
|
+
}
|
|
24
|
+
function generateUniqueId(text, prefix = "", suffix = "") {
|
|
25
|
+
const slug = text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim().substring(0, 50);
|
|
26
|
+
const parts = [prefix, slug, suffix].filter(Boolean);
|
|
27
|
+
return parts.join("-");
|
|
28
|
+
}
|
|
29
|
+
function truncateText(text, maxLength, suffix = "...") {
|
|
30
|
+
if (!text || text.length <= maxLength) {
|
|
31
|
+
return text || "";
|
|
32
|
+
}
|
|
33
|
+
return text.substring(0, maxLength - suffix.length) + suffix;
|
|
34
|
+
}
|
|
35
|
+
function capitalize(text, options = {}) {
|
|
36
|
+
if (!text) return "";
|
|
37
|
+
const { firstWordOnly = false, lowerRest = false } = options;
|
|
38
|
+
if (firstWordOnly) {
|
|
39
|
+
return text.charAt(0).toUpperCase() + (lowerRest ? text.slice(1).toLowerCase() : text.slice(1));
|
|
40
|
+
}
|
|
41
|
+
if (lowerRest) {
|
|
42
|
+
return text.replace(/\b\w/g, (char) => char.toUpperCase()).toLowerCase();
|
|
43
|
+
}
|
|
44
|
+
return text.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
45
|
+
}
|
|
46
|
+
function cleanText(text, allowSpaces = true) {
|
|
47
|
+
if (!text) return "";
|
|
48
|
+
const pattern = allowSpaces ? /[^\w\s]/g : /[^\w]/g;
|
|
49
|
+
return text.replace(pattern, "");
|
|
50
|
+
}
|
|
51
|
+
function countWords(text) {
|
|
52
|
+
if (!text || !text.trim()) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
return text.trim().split(/\s+/).length;
|
|
56
|
+
}
|
|
57
|
+
function isEmpty(text) {
|
|
58
|
+
return !text || !text.trim();
|
|
59
|
+
}
|
|
60
|
+
function normalizeSpaces(text, options = {}) {
|
|
61
|
+
if (!text) return "";
|
|
62
|
+
const { newlines = false } = options;
|
|
63
|
+
let cleaned = text;
|
|
64
|
+
if (newlines) {
|
|
65
|
+
cleaned = cleaned.replace(/\s+/g, " ");
|
|
66
|
+
} else {
|
|
67
|
+
cleaned = cleaned.replace(/\s+/g, " ");
|
|
68
|
+
}
|
|
69
|
+
return cleaned.trim();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/string/index.ts
|
|
73
|
+
function textToSlug(text) {
|
|
74
|
+
return text.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/date/index.ts
|
|
78
|
+
var RELATIVE_TEXTS = {
|
|
79
|
+
"pt-BR": {
|
|
80
|
+
now: "agora",
|
|
81
|
+
minute: (n) => `h\xE1 ${n} ${n === 1 ? "minuto" : "minutos"}`,
|
|
82
|
+
hour: (n) => `h\xE1 ${n} ${n === 1 ? "hora" : "horas"}`,
|
|
83
|
+
day: (n) => `h\xE1 ${n} ${n === 1 ? "dia" : "dias"}`,
|
|
84
|
+
month: (n) => `h\xE1 ${n} ${n === 1 ? "m\xEAs" : "meses"}`,
|
|
85
|
+
year: (n) => `h\xE1 ${n} ${n === 1 ? "ano" : "anos"}`
|
|
86
|
+
},
|
|
87
|
+
"en-US": {
|
|
88
|
+
now: "now",
|
|
89
|
+
minute: (n) => `${n} ${n === 1 ? "minute" : "minutes"} ago`,
|
|
90
|
+
hour: (n) => `${n} ${n === 1 ? "hour" : "hours"} ago`,
|
|
91
|
+
day: (n) => `${n} ${n === 1 ? "day" : "days"} ago`,
|
|
92
|
+
month: (n) => `${n} ${n === 1 ? "month" : "months"} ago`,
|
|
93
|
+
year: (n) => `${n} ${n === 1 ? "year" : "years"} ago`
|
|
94
|
+
},
|
|
95
|
+
"es-ES": {
|
|
96
|
+
now: "ahora",
|
|
97
|
+
minute: (n) => `hace ${n} ${n === 1 ? "minuto" : "minutos"}`,
|
|
98
|
+
hour: (n) => `hace ${n} ${n === 1 ? "hora" : "horas"}`,
|
|
99
|
+
day: (n) => `hace ${n} ${n === 1 ? "d\xEDa" : "d\xEDas"}`,
|
|
100
|
+
month: (n) => `hace ${n} ${n === 1 ? "mes" : "meses"}`,
|
|
101
|
+
year: (n) => `hace ${n} ${n === 1 ? "a\xF1o" : "a\xF1os"}`
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
function formatDate(date, format = "long", locale = DEFAULT_LOCALE) {
|
|
105
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
106
|
+
const options = {
|
|
107
|
+
day: "numeric",
|
|
108
|
+
month: format === "short" ? "2-digit" : "long",
|
|
109
|
+
year: "numeric",
|
|
110
|
+
...format === "full" && { weekday: "long" }
|
|
111
|
+
};
|
|
112
|
+
if (format === "short") {
|
|
113
|
+
return d.toLocaleDateString(locale, { day: "2-digit", month: "2-digit", year: "numeric" });
|
|
114
|
+
}
|
|
115
|
+
return d.toLocaleDateString(locale, options);
|
|
116
|
+
}
|
|
117
|
+
function formatDateTime(date, locale = DEFAULT_LOCALE) {
|
|
118
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
119
|
+
return d.toLocaleString(locale, {
|
|
120
|
+
day: "numeric",
|
|
121
|
+
month: "long",
|
|
122
|
+
year: "numeric",
|
|
123
|
+
hour: "2-digit",
|
|
124
|
+
minute: "2-digit"
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function formatRelativeDate(date, locale = DEFAULT_LOCALE) {
|
|
128
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
129
|
+
if (!(d instanceof Date) || Number.isNaN(d.getTime())) {
|
|
130
|
+
return "";
|
|
131
|
+
}
|
|
132
|
+
const now = /* @__PURE__ */ new Date();
|
|
133
|
+
const diffMs = now.getTime() - d.getTime();
|
|
134
|
+
const diffSec = Math.floor(diffMs / 1e3);
|
|
135
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
136
|
+
const diffHour = Math.floor(diffMin / 60);
|
|
137
|
+
const diffDay = Math.floor(diffHour / 24);
|
|
138
|
+
const diffMonth = Math.floor(diffDay / 30.4375);
|
|
139
|
+
const diffYear = Math.floor(diffDay / 365);
|
|
140
|
+
const texts = RELATIVE_TEXTS[locale];
|
|
141
|
+
if (diffSec < 10) {
|
|
142
|
+
if (locale === "pt-BR") return "agora mesmo";
|
|
143
|
+
if (locale === "en-US") return "just now";
|
|
144
|
+
if (locale === "es-ES") return "ahora mismo";
|
|
145
|
+
}
|
|
146
|
+
if (diffSec < 60) return texts.now;
|
|
147
|
+
if (diffMin < 60) return texts.minute(diffMin);
|
|
148
|
+
if (diffHour < 24) return texts.hour(diffHour);
|
|
149
|
+
if (diffDay === 1) {
|
|
150
|
+
if (locale === "pt-BR") return "ontem";
|
|
151
|
+
if (locale === "en-US") return "yesterday";
|
|
152
|
+
if (locale === "es-ES") return "ayer";
|
|
153
|
+
}
|
|
154
|
+
if (diffDay === 2) {
|
|
155
|
+
if (locale === "pt-BR") return "anteontem";
|
|
156
|
+
if (locale === "en-US") return "the day before yesterday";
|
|
157
|
+
if (locale === "es-ES") return "anteayer";
|
|
158
|
+
}
|
|
159
|
+
if (diffDay < 30) return texts.day(diffDay);
|
|
160
|
+
if (diffMonth < 12) return texts.month(diffMonth);
|
|
161
|
+
return texts.year(diffYear);
|
|
162
|
+
}
|
|
163
|
+
function toISOString(date) {
|
|
164
|
+
return date.toISOString();
|
|
165
|
+
}
|
|
166
|
+
function isValidDate(date) {
|
|
167
|
+
return date instanceof Date && !isNaN(date.getTime());
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/number/index.ts
|
|
171
|
+
function formatCurrency(value, locale = DEFAULT_LOCALE, options) {
|
|
172
|
+
const currency = CURRENCY_MAP[locale];
|
|
173
|
+
return new Intl.NumberFormat(locale, {
|
|
174
|
+
style: "currency",
|
|
175
|
+
currency,
|
|
176
|
+
...options
|
|
177
|
+
}).format(value);
|
|
178
|
+
}
|
|
179
|
+
function formatNumber(value, decimals = 0, locale = DEFAULT_LOCALE) {
|
|
180
|
+
return new Intl.NumberFormat(locale, {
|
|
181
|
+
minimumFractionDigits: decimals,
|
|
182
|
+
maximumFractionDigits: decimals
|
|
183
|
+
}).format(value);
|
|
184
|
+
}
|
|
185
|
+
function formatCompact(value, decimals = 1, locale = DEFAULT_LOCALE) {
|
|
186
|
+
return new Intl.NumberFormat(locale, {
|
|
187
|
+
notation: "compact",
|
|
188
|
+
compactDisplay: "short",
|
|
189
|
+
minimumFractionDigits: decimals,
|
|
190
|
+
maximumFractionDigits: decimals
|
|
191
|
+
}).format(value);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/status/index.ts
|
|
195
|
+
var STATUS_TRANSLATIONS = {
|
|
196
|
+
"pt-BR": {
|
|
197
|
+
// Estados de conteúdo
|
|
198
|
+
DRAFT: "Rascunho",
|
|
199
|
+
PUBLISHED: "Publicado",
|
|
200
|
+
ARCHIVED: "Arquivado",
|
|
201
|
+
SCHEDULED: "Agendado",
|
|
202
|
+
DELETED: "Exclu\xEDdo",
|
|
203
|
+
// Estados de processo
|
|
204
|
+
PENDING: "Pendente",
|
|
205
|
+
ACTIVE: "Ativo",
|
|
206
|
+
INACTIVE: "Inativo",
|
|
207
|
+
COMPLETED: "Conclu\xEDdo",
|
|
208
|
+
CANCELLED: "Cancelado",
|
|
209
|
+
// Estados de aprovação
|
|
210
|
+
APPROVED: "Aprovado",
|
|
211
|
+
REJECTED: "Rejeitado",
|
|
212
|
+
// Estados de pedido/pagamento
|
|
213
|
+
PROCESSING: "Processando",
|
|
214
|
+
PAID: "Pago",
|
|
215
|
+
UNPAID: "N\xE3o Pago",
|
|
216
|
+
REFUNDED: "Reembolsado",
|
|
217
|
+
FAILED: "Falhou",
|
|
218
|
+
// Estados de usuário
|
|
219
|
+
VERIFIED: "Verificado",
|
|
220
|
+
UNVERIFIED: "N\xE3o Verificado",
|
|
221
|
+
BANNED: "Banido",
|
|
222
|
+
SUSPENDED: "Suspenso"
|
|
223
|
+
},
|
|
224
|
+
"en-US": {
|
|
225
|
+
DRAFT: "Draft",
|
|
226
|
+
PUBLISHED: "Published",
|
|
227
|
+
ARCHIVED: "Archived",
|
|
228
|
+
SCHEDULED: "Scheduled",
|
|
229
|
+
DELETED: "Deleted",
|
|
230
|
+
PENDING: "Pending",
|
|
231
|
+
ACTIVE: "Active",
|
|
232
|
+
INACTIVE: "Inactive",
|
|
233
|
+
COMPLETED: "Completed",
|
|
234
|
+
CANCELLED: "Cancelled",
|
|
235
|
+
APPROVED: "Approved",
|
|
236
|
+
REJECTED: "Rejected",
|
|
237
|
+
PROCESSING: "Processing",
|
|
238
|
+
PAID: "Paid",
|
|
239
|
+
UNPAID: "Unpaid",
|
|
240
|
+
REFUNDED: "Refunded",
|
|
241
|
+
FAILED: "Failed",
|
|
242
|
+
VERIFIED: "Verified",
|
|
243
|
+
UNVERIFIED: "Unverified",
|
|
244
|
+
BANNED: "Banned",
|
|
245
|
+
SUSPENDED: "Suspended"
|
|
246
|
+
},
|
|
247
|
+
"es-ES": {
|
|
248
|
+
DRAFT: "Borrador",
|
|
249
|
+
PUBLISHED: "Publicado",
|
|
250
|
+
ARCHIVED: "Archivado",
|
|
251
|
+
SCHEDULED: "Programado",
|
|
252
|
+
DELETED: "Eliminado",
|
|
253
|
+
PENDING: "Pendiente",
|
|
254
|
+
ACTIVE: "Activo",
|
|
255
|
+
INACTIVE: "Inactivo",
|
|
256
|
+
COMPLETED: "Completado",
|
|
257
|
+
CANCELLED: "Cancelado",
|
|
258
|
+
APPROVED: "Aprobado",
|
|
259
|
+
REJECTED: "Rechazado",
|
|
260
|
+
PROCESSING: "Procesando",
|
|
261
|
+
PAID: "Pagado",
|
|
262
|
+
UNPAID: "No Pagado",
|
|
263
|
+
REFUNDED: "Reembolsado",
|
|
264
|
+
FAILED: "Fallido",
|
|
265
|
+
VERIFIED: "Verificado",
|
|
266
|
+
UNVERIFIED: "No Verificado",
|
|
267
|
+
BANNED: "Bloqueado",
|
|
268
|
+
SUSPENDED: "Suspendido"
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
function translateStatus(status, locale = DEFAULT_LOCALE) {
|
|
272
|
+
const normalized = status.toUpperCase();
|
|
273
|
+
return STATUS_TRANSLATIONS[locale][normalized] || status;
|
|
274
|
+
}
|
|
275
|
+
function getStatusColor(status) {
|
|
276
|
+
const normalized = status.toUpperCase();
|
|
277
|
+
const colorMap = {
|
|
278
|
+
DRAFT: "text-gray-600",
|
|
279
|
+
PENDING: "text-yellow-600",
|
|
280
|
+
PUBLISHED: "text-green-600",
|
|
281
|
+
ACTIVE: "text-green-600",
|
|
282
|
+
INACTIVE: "text-gray-600",
|
|
283
|
+
ARCHIVED: "text-orange-600",
|
|
284
|
+
DELETED: "text-red-600",
|
|
285
|
+
SCHEDULED: "text-blue-600",
|
|
286
|
+
COMPLETED: "text-green-600",
|
|
287
|
+
CANCELLED: "text-red-600",
|
|
288
|
+
APPROVED: "text-green-600",
|
|
289
|
+
REJECTED: "text-red-600",
|
|
290
|
+
FAILED: "text-red-600",
|
|
291
|
+
VERIFIED: "text-green-600",
|
|
292
|
+
BANNED: "text-red-600"
|
|
293
|
+
};
|
|
294
|
+
return colorMap[normalized] || "text-gray-600";
|
|
295
|
+
}
|
|
296
|
+
function getStatusVariant(status) {
|
|
297
|
+
const normalized = status.toUpperCase();
|
|
298
|
+
if (["PUBLISHED", "ACTIVE", "COMPLETED", "APPROVED", "VERIFIED"].includes(normalized)) {
|
|
299
|
+
return "default";
|
|
300
|
+
}
|
|
301
|
+
if (["DELETED", "CANCELLED", "REJECTED", "FAILED", "BANNED"].includes(normalized)) {
|
|
302
|
+
return "destructive";
|
|
303
|
+
}
|
|
304
|
+
if (["DRAFT", "INACTIVE", "ARCHIVED"].includes(normalized)) {
|
|
305
|
+
return "secondary";
|
|
306
|
+
}
|
|
307
|
+
return "outline";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/validation/index.ts
|
|
311
|
+
function validateEmail(email, locale = DEFAULT_LOCALE) {
|
|
312
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
313
|
+
const isValid = emailRegex.test(email);
|
|
314
|
+
if (!isValid) {
|
|
315
|
+
const errors = {
|
|
316
|
+
"pt-BR": ["Email inv\xE1lido"],
|
|
317
|
+
"en-US": ["Invalid email"],
|
|
318
|
+
"es-ES": ["Email inv\xE1lido"]
|
|
319
|
+
};
|
|
320
|
+
return {
|
|
321
|
+
isValid: false,
|
|
322
|
+
errors: errors[locale] || errors["pt-BR"]
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
return { isValid: true };
|
|
326
|
+
}
|
|
327
|
+
function validatePassword(password, options = {}, locale = DEFAULT_LOCALE) {
|
|
328
|
+
const {
|
|
329
|
+
minLength = 8,
|
|
330
|
+
requireUppercase = true,
|
|
331
|
+
requireLowercase = true,
|
|
332
|
+
requireNumbers = true,
|
|
333
|
+
requireSpecialChars = false
|
|
334
|
+
} = options;
|
|
335
|
+
const errors = [];
|
|
336
|
+
const errorMessages = {
|
|
337
|
+
"pt-BR": {
|
|
338
|
+
minLength: `Senha deve ter pelo menos ${minLength} caracteres`,
|
|
339
|
+
uppercase: "Senha deve conter pelo menos uma letra mai\xFAscula",
|
|
340
|
+
lowercase: "Senha deve conter pelo menos uma letra min\xFAscula",
|
|
341
|
+
numbers: "Senha deve conter pelo menos um n\xFAmero",
|
|
342
|
+
specialChars: "Senha deve conter pelo menos um caractere especial"
|
|
343
|
+
},
|
|
344
|
+
"en-US": {
|
|
345
|
+
minLength: `Password must be at least ${minLength} characters`,
|
|
346
|
+
uppercase: "Password must contain at least one uppercase letter",
|
|
347
|
+
lowercase: "Password must contain at least one lowercase letter",
|
|
348
|
+
numbers: "Password must contain at least one number",
|
|
349
|
+
specialChars: "Password must contain at least one special character"
|
|
350
|
+
},
|
|
351
|
+
"es-ES": {
|
|
352
|
+
minLength: `La contrase\xF1a debe tener al menos ${minLength} caracteres`,
|
|
353
|
+
uppercase: "La contrase\xF1a debe contener al menos una letra may\xFAscula",
|
|
354
|
+
lowercase: "La contrase\xF1a debe contener al menos una letra min\xFAscula",
|
|
355
|
+
numbers: "La contrase\xF1a debe contener al menos un n\xFAmero",
|
|
356
|
+
specialChars: "La contrase\xF1a debe contener al menos un car\xE1cter especial"
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
const messages = errorMessages[locale] || errorMessages["pt-BR"];
|
|
360
|
+
if (password.length < minLength) {
|
|
361
|
+
errors.push(messages.minLength);
|
|
362
|
+
}
|
|
363
|
+
if (requireUppercase && !/[A-Z]/.test(password)) {
|
|
364
|
+
errors.push(messages.uppercase);
|
|
365
|
+
}
|
|
366
|
+
if (requireLowercase && !/[a-z]/.test(password)) {
|
|
367
|
+
errors.push(messages.lowercase);
|
|
368
|
+
}
|
|
369
|
+
if (requireNumbers && !/\d/.test(password)) {
|
|
370
|
+
errors.push(messages.numbers);
|
|
371
|
+
}
|
|
372
|
+
if (requireSpecialChars && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
|
|
373
|
+
errors.push(messages.specialChars);
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
isValid: errors.length === 0,
|
|
377
|
+
errors
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function validateUrl(url, locale = DEFAULT_LOCALE) {
|
|
381
|
+
try {
|
|
382
|
+
new URL(url);
|
|
383
|
+
return { isValid: true };
|
|
384
|
+
} catch {
|
|
385
|
+
const errors = {
|
|
386
|
+
"pt-BR": ["URL inv\xE1lida"],
|
|
387
|
+
"en-US": ["Invalid URL"],
|
|
388
|
+
"es-ES": ["URL inv\xE1lida"]
|
|
389
|
+
};
|
|
390
|
+
return {
|
|
391
|
+
isValid: false,
|
|
392
|
+
errors: errors[locale] || errors["pt-BR"]
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function validatePhone(phone, locale = DEFAULT_LOCALE) {
|
|
397
|
+
const phoneRegex = /^\(?\d{2}\)?[\s-]?\d{4,5}[-]?\d{4}$/;
|
|
398
|
+
const isValid = phoneRegex.test(phone);
|
|
399
|
+
if (!isValid) {
|
|
400
|
+
const errors = {
|
|
401
|
+
"pt-BR": ["Telefone inv\xE1lido"],
|
|
402
|
+
"en-US": ["Invalid phone number"],
|
|
403
|
+
"es-ES": ["Tel\xE9fono inv\xE1lido"]
|
|
404
|
+
};
|
|
405
|
+
return {
|
|
406
|
+
isValid: false,
|
|
407
|
+
errors: errors[locale] || errors["pt-BR"]
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
return { isValid: true };
|
|
411
|
+
}
|
|
412
|
+
function validateUsername(username, options = {}, locale = DEFAULT_LOCALE) {
|
|
413
|
+
const {
|
|
414
|
+
minLength = 3,
|
|
415
|
+
maxLength = 20,
|
|
416
|
+
allowSpecialChars = false
|
|
417
|
+
} = options;
|
|
418
|
+
const errors = [];
|
|
419
|
+
const errorMessages = {
|
|
420
|
+
"pt-BR": {
|
|
421
|
+
minLength: `Username muito curto (m\xEDnimo ${minLength} caracteres)`,
|
|
422
|
+
maxLength: `Username muito longo (m\xE1ximo ${maxLength} caracteres)`,
|
|
423
|
+
invalidChars: "Username cont\xE9m caracteres inv\xE1lidos"
|
|
424
|
+
},
|
|
425
|
+
"en-US": {
|
|
426
|
+
minLength: `Username too short (minimum ${minLength} characters)`,
|
|
427
|
+
maxLength: `Username too long (maximum ${maxLength} characters)`,
|
|
428
|
+
invalidChars: "Username contains invalid characters"
|
|
429
|
+
},
|
|
430
|
+
"es-ES": {
|
|
431
|
+
minLength: `Username muy corto (m\xEDnimo ${minLength} caracteres)`,
|
|
432
|
+
maxLength: `Username muy largo (m\xE1ximo ${maxLength} caracteres)`,
|
|
433
|
+
invalidChars: "Username contiene caracteres inv\xE1lidos"
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
const messages = errorMessages[locale] || errorMessages["pt-BR"];
|
|
437
|
+
if (username.length < minLength) {
|
|
438
|
+
errors.push(messages.minLength);
|
|
439
|
+
}
|
|
440
|
+
if (username.length > maxLength) {
|
|
441
|
+
errors.push(messages.maxLength);
|
|
442
|
+
}
|
|
443
|
+
const usernameRegex = allowSpecialChars ? /^[a-zA-Z0-9_]{3,20}$/ : /^[a-zA-Z0-9_]{3,20}$/;
|
|
444
|
+
if (!usernameRegex.test(username)) {
|
|
445
|
+
errors.push(messages.invalidChars);
|
|
446
|
+
}
|
|
447
|
+
return {
|
|
448
|
+
isValid: errors.length === 0,
|
|
449
|
+
errors
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function validateSlug(slug, options = {}, locale = DEFAULT_LOCALE) {
|
|
453
|
+
const {
|
|
454
|
+
minLength = 3,
|
|
455
|
+
maxLength = 100
|
|
456
|
+
} = options;
|
|
457
|
+
const errors = [];
|
|
458
|
+
const errorMessages = {
|
|
459
|
+
"pt-BR": {
|
|
460
|
+
minLength: `Slug muito curto (m\xEDnimo ${minLength} caracteres)`,
|
|
461
|
+
maxLength: `Slug muito longo (m\xE1ximo ${maxLength} caracteres)`,
|
|
462
|
+
invalidFormat: "Slug inv\xE1lido - use apenas letras min\xFAsculas, n\xFAmeros e h\xEDfens"
|
|
463
|
+
},
|
|
464
|
+
"en-US": {
|
|
465
|
+
minLength: `Slug too short (minimum ${minLength} characters)`,
|
|
466
|
+
maxLength: `Slug too long (maximum ${maxLength} characters)`,
|
|
467
|
+
invalidFormat: "Invalid slug - use only lowercase letters, numbers and hyphens"
|
|
468
|
+
},
|
|
469
|
+
"es-ES": {
|
|
470
|
+
minLength: `Slug muy corto (m\xEDnimo ${minLength} caracteres)`,
|
|
471
|
+
maxLength: `Slug muy largo (m\xE1ximo ${maxLength} caracteres)`,
|
|
472
|
+
invalidFormat: "Slug inv\xE1lido - use solo letras min\xFAsculas, n\xFAmeros y guiones"
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
const messages = errorMessages[locale] || errorMessages["pt-BR"];
|
|
476
|
+
if (slug.length < minLength) {
|
|
477
|
+
errors.push(messages.minLength);
|
|
478
|
+
}
|
|
479
|
+
if (slug.length > maxLength) {
|
|
480
|
+
errors.push(messages.maxLength);
|
|
481
|
+
}
|
|
482
|
+
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
483
|
+
if (!slugRegex.test(slug)) {
|
|
484
|
+
errors.push(messages.invalidFormat);
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
isValid: errors.length === 0,
|
|
488
|
+
errors
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
function validateText(text, options = {}, locale = DEFAULT_LOCALE) {
|
|
492
|
+
const {
|
|
493
|
+
minLength = 0,
|
|
494
|
+
maxLength = Infinity,
|
|
495
|
+
fieldName = "Texto"
|
|
496
|
+
} = options;
|
|
497
|
+
const errors = [];
|
|
498
|
+
const errorMessages = {
|
|
499
|
+
"pt-BR": {
|
|
500
|
+
minLength: `${fieldName} muito curto (m\xEDnimo ${minLength} caracteres)`,
|
|
501
|
+
maxLength: `${fieldName} muito longo (m\xE1ximo ${maxLength} caracteres)`
|
|
502
|
+
},
|
|
503
|
+
"en-US": {
|
|
504
|
+
minLength: `${fieldName} too short (minimum ${minLength} characters)`,
|
|
505
|
+
maxLength: `${fieldName} too long (maximum ${maxLength} characters)`
|
|
506
|
+
},
|
|
507
|
+
"es-ES": {
|
|
508
|
+
minLength: `${fieldName} muy corto (m\xEDnimo ${minLength} caracteres)`,
|
|
509
|
+
maxLength: `${fieldName} muy largo (m\xE1ximo ${maxLength} caracteres)`
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
const messages = errorMessages[locale] || errorMessages["pt-BR"];
|
|
513
|
+
if (text.length < minLength) {
|
|
514
|
+
errors.push(messages.minLength);
|
|
515
|
+
}
|
|
516
|
+
if (text.length > maxLength) {
|
|
517
|
+
errors.push(messages.maxLength);
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
isValid: errors.length === 0,
|
|
521
|
+
errors
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/dom/index.ts
|
|
526
|
+
function prefersReducedMotion() {
|
|
527
|
+
if (typeof window === "undefined") return false;
|
|
528
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
529
|
+
}
|
|
530
|
+
function onReducedMotionChange(callback) {
|
|
531
|
+
if (typeof window === "undefined") {
|
|
532
|
+
return () => {
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
536
|
+
const handleChange = (e) => {
|
|
537
|
+
callback(e.matches);
|
|
538
|
+
};
|
|
539
|
+
if (mediaQuery.addEventListener) {
|
|
540
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
541
|
+
} else {
|
|
542
|
+
mediaQuery.addListener(handleChange);
|
|
543
|
+
}
|
|
544
|
+
return () => {
|
|
545
|
+
if (mediaQuery.removeEventListener) {
|
|
546
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
547
|
+
} else {
|
|
548
|
+
mediaQuery.removeListener(handleChange);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
function scrollToPosition(x = 0, y = 0, options = {}) {
|
|
553
|
+
if (typeof window === "undefined") return;
|
|
554
|
+
const { smooth = false, behavior } = options;
|
|
555
|
+
window.scrollTo({
|
|
556
|
+
left: x,
|
|
557
|
+
top: y,
|
|
558
|
+
behavior: behavior || (smooth ? "smooth" : "auto")
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
function scrollToTop(smooth = false) {
|
|
562
|
+
scrollToPosition(0, 0, { smooth });
|
|
563
|
+
}
|
|
564
|
+
function smoothScrollTo(x, y, duration = 300) {
|
|
565
|
+
if (typeof window === "undefined") return;
|
|
566
|
+
const startX = window.scrollX;
|
|
567
|
+
const startY = window.scrollY;
|
|
568
|
+
const distanceX = x - startX;
|
|
569
|
+
const distanceY = y - startY;
|
|
570
|
+
const startTime = performance.now();
|
|
571
|
+
function animate(currentTime) {
|
|
572
|
+
const elapsed = currentTime - startTime;
|
|
573
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
574
|
+
const easeProgress = 1 - Math.pow(1 - progress, 3);
|
|
575
|
+
const currentX = startX + distanceX * easeProgress;
|
|
576
|
+
const currentY = startY + distanceY * easeProgress;
|
|
577
|
+
window.scrollTo(currentX, currentY);
|
|
578
|
+
if (progress < 1) {
|
|
579
|
+
requestAnimationFrame(animate);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
requestAnimationFrame(animate);
|
|
583
|
+
}
|
|
584
|
+
function scrollToElement(element, options = {}) {
|
|
585
|
+
if (typeof window === "undefined") return;
|
|
586
|
+
const { smooth = false, offset = 0, behavior } = options;
|
|
587
|
+
let targetElement;
|
|
588
|
+
if (typeof element === "string") {
|
|
589
|
+
targetElement = document.querySelector(element);
|
|
590
|
+
} else {
|
|
591
|
+
targetElement = element;
|
|
592
|
+
}
|
|
593
|
+
if (!targetElement) return;
|
|
594
|
+
const rect = targetElement.getBoundingClientRect();
|
|
595
|
+
const absoluteY = rect.top + window.scrollY - offset;
|
|
596
|
+
window.scrollTo({
|
|
597
|
+
left: 0,
|
|
598
|
+
top: absoluteY,
|
|
599
|
+
behavior: behavior || (smooth ? "smooth" : "auto")
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
function isElementVisible(element, threshold = 0) {
|
|
603
|
+
if (typeof window === "undefined") return false;
|
|
604
|
+
let targetElement;
|
|
605
|
+
if (typeof element === "string") {
|
|
606
|
+
targetElement = document.querySelector(element);
|
|
607
|
+
} else {
|
|
608
|
+
targetElement = element;
|
|
609
|
+
}
|
|
610
|
+
if (!targetElement) return false;
|
|
611
|
+
const rect = targetElement.getBoundingClientRect();
|
|
612
|
+
const windowHeight = window.innerHeight;
|
|
613
|
+
const windowWidth = window.innerWidth;
|
|
614
|
+
const verticalThreshold = windowHeight * threshold;
|
|
615
|
+
const horizontalThreshold = windowWidth * threshold;
|
|
616
|
+
const isVisibleVertically = rect.bottom >= verticalThreshold && rect.top <= windowHeight - verticalThreshold;
|
|
617
|
+
const isVisibleHorizontally = rect.right >= horizontalThreshold && rect.left <= windowWidth - horizontalThreshold;
|
|
618
|
+
return isVisibleVertically && isVisibleHorizontally;
|
|
619
|
+
}
|
|
620
|
+
function getElementPosition(element) {
|
|
621
|
+
if (typeof window === "undefined") return null;
|
|
622
|
+
let targetElement;
|
|
623
|
+
if (typeof element === "string") {
|
|
624
|
+
targetElement = document.querySelector(element);
|
|
625
|
+
} else {
|
|
626
|
+
targetElement = element;
|
|
627
|
+
}
|
|
628
|
+
if (!targetElement) return null;
|
|
629
|
+
const rect = targetElement.getBoundingClientRect();
|
|
630
|
+
return {
|
|
631
|
+
x: rect.left + window.scrollX,
|
|
632
|
+
y: rect.top + window.scrollY
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
function isMobile() {
|
|
636
|
+
if (typeof window === "undefined") return false;
|
|
637
|
+
const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
638
|
+
navigator.userAgent
|
|
639
|
+
);
|
|
640
|
+
const isMobileScreen = window.innerWidth <= 768;
|
|
641
|
+
return isMobileUA || isMobileScreen;
|
|
642
|
+
}
|
|
643
|
+
function isDarkMode() {
|
|
644
|
+
if (typeof window === "undefined") return false;
|
|
645
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
646
|
+
}
|
|
647
|
+
function onDarkModeChange(callback) {
|
|
648
|
+
if (typeof window === "undefined") {
|
|
649
|
+
return () => {
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
653
|
+
const handleChange = (e) => {
|
|
654
|
+
callback(e.matches);
|
|
655
|
+
};
|
|
656
|
+
if (mediaQuery.addEventListener) {
|
|
657
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
658
|
+
} else {
|
|
659
|
+
mediaQuery.addListener(handleChange);
|
|
660
|
+
}
|
|
661
|
+
return () => {
|
|
662
|
+
if (mediaQuery.removeEventListener) {
|
|
663
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
664
|
+
} else {
|
|
665
|
+
mediaQuery.removeListener(handleChange);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
async function copyToClipboard(text) {
|
|
670
|
+
if (typeof window === "undefined") return false;
|
|
671
|
+
try {
|
|
672
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
673
|
+
await navigator.clipboard.writeText(text);
|
|
674
|
+
return true;
|
|
675
|
+
}
|
|
676
|
+
const textArea = document.createElement("textarea");
|
|
677
|
+
textArea.value = text;
|
|
678
|
+
textArea.style.position = "fixed";
|
|
679
|
+
textArea.style.left = "-999999px";
|
|
680
|
+
textArea.style.top = "-999999px";
|
|
681
|
+
document.body.appendChild(textArea);
|
|
682
|
+
textArea.focus();
|
|
683
|
+
textArea.select();
|
|
684
|
+
const result = document.execCommand("copy");
|
|
685
|
+
document.body.removeChild(textArea);
|
|
686
|
+
return result;
|
|
687
|
+
} catch {
|
|
688
|
+
return false;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
function downloadFile(blob, filename) {
|
|
692
|
+
if (typeof window === "undefined") return;
|
|
693
|
+
const url = URL.createObjectURL(blob);
|
|
694
|
+
const link = document.createElement("a");
|
|
695
|
+
link.href = url;
|
|
696
|
+
link.download = filename;
|
|
697
|
+
document.body.appendChild(link);
|
|
698
|
+
link.click();
|
|
699
|
+
document.body.removeChild(link);
|
|
700
|
+
URL.revokeObjectURL(url);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// src/stats/index.ts
|
|
704
|
+
function formatNumber2(num) {
|
|
705
|
+
if (num >= 1e6) {
|
|
706
|
+
return (num / 1e6).toFixed(1) + "M";
|
|
707
|
+
}
|
|
708
|
+
if (num >= 1e3) {
|
|
709
|
+
return (num / 1e3).toFixed(1) + "k";
|
|
710
|
+
}
|
|
711
|
+
return num.toString();
|
|
712
|
+
}
|
|
713
|
+
function calculateChange(current, previous) {
|
|
714
|
+
if (previous === 0) return 100;
|
|
715
|
+
return Math.round((current - previous) / previous * 100);
|
|
716
|
+
}
|
|
717
|
+
function formatPercentage(value, options = {}) {
|
|
718
|
+
const { showSign = true, decimals = 0 } = options;
|
|
719
|
+
const sign = showSign && value > 0 ? "+" : "";
|
|
720
|
+
const formattedValue = value.toFixed(decimals);
|
|
721
|
+
return `${sign}${formattedValue}%`;
|
|
722
|
+
}
|
|
723
|
+
function generateMockChartData(days, locale = "pt-BR") {
|
|
724
|
+
const data = [];
|
|
725
|
+
const now = /* @__PURE__ */ new Date();
|
|
726
|
+
for (let i = days - 1; i >= 0; i--) {
|
|
727
|
+
const date = new Date(now);
|
|
728
|
+
date.setDate(date.getDate() - i);
|
|
729
|
+
data.push({
|
|
730
|
+
date: date.toLocaleDateString(locale, {
|
|
731
|
+
day: "2-digit",
|
|
732
|
+
month: "2-digit"
|
|
733
|
+
}),
|
|
734
|
+
views: Math.floor(Math.random() * 1e3) + 500,
|
|
735
|
+
uniqueViews: Math.floor(Math.random() * 700) + 300,
|
|
736
|
+
likes: Math.floor(Math.random() * 100) + 50,
|
|
737
|
+
comments: Math.floor(Math.random() * 50) + 10,
|
|
738
|
+
shares: Math.floor(Math.random() * 30) + 5
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
return data;
|
|
742
|
+
}
|
|
743
|
+
function groupDataByPeriod(data) {
|
|
744
|
+
return data;
|
|
745
|
+
}
|
|
746
|
+
function calculateMovingAverage(data, window2) {
|
|
747
|
+
const result = [];
|
|
748
|
+
for (let i = window2 - 1; i < data.length; i++) {
|
|
749
|
+
const sum = data.slice(i - window2 + 1, i + 1).reduce((a, b) => a + b, 0);
|
|
750
|
+
result.push(sum / window2);
|
|
751
|
+
}
|
|
752
|
+
return result;
|
|
753
|
+
}
|
|
754
|
+
function findMinMax(data, field) {
|
|
755
|
+
const values = data.map((item) => Number(item[field]) || 0);
|
|
756
|
+
return {
|
|
757
|
+
min: Math.min(...values),
|
|
758
|
+
max: Math.max(...values)
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// src/pt-br.ts
|
|
763
|
+
var pt_br_exports = {};
|
|
764
|
+
__export(pt_br_exports, {
|
|
765
|
+
formatCompact: () => formatCompact2,
|
|
766
|
+
formatCurrency: () => formatCurrency2,
|
|
767
|
+
formatDate: () => formatDate2,
|
|
768
|
+
formatDateTime: () => formatDateTime2,
|
|
769
|
+
formatNumber: () => formatNumber3,
|
|
770
|
+
formatRelativeDate: () => formatRelativeDate2,
|
|
771
|
+
translateStatus: () => translateStatus2
|
|
772
|
+
});
|
|
773
|
+
function formatDate2(date, format = "long") {
|
|
774
|
+
return formatDate(date, format, "pt-BR");
|
|
775
|
+
}
|
|
776
|
+
function formatDateTime2(date) {
|
|
777
|
+
return formatDateTime(date, "pt-BR");
|
|
778
|
+
}
|
|
779
|
+
function formatRelativeDate2(date) {
|
|
780
|
+
return formatRelativeDate(date, "pt-BR");
|
|
781
|
+
}
|
|
782
|
+
function formatCurrency2(value, options) {
|
|
783
|
+
return formatCurrency(value, "pt-BR", options);
|
|
784
|
+
}
|
|
785
|
+
function formatNumber3(value, decimals = 0) {
|
|
786
|
+
return formatNumber(value, decimals, "pt-BR");
|
|
787
|
+
}
|
|
788
|
+
function formatCompact2(value, decimals = 1) {
|
|
789
|
+
return formatCompact(value, decimals, "pt-BR");
|
|
790
|
+
}
|
|
791
|
+
function translateStatus2(status) {
|
|
792
|
+
return translateStatus(status, "pt-BR");
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
export { CURRENCY_MAP, DEFAULT_LOCALE, calculateChange, calculateMovingAverage, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatCurrency, formatDate, formatDateTime, formatNumber2 as formatNumber, formatPercentage, formatRelativeDate, generateMockChartData, generateUniqueId, getElementPosition, getStatusColor, getStatusVariant, groupDataByPeriod, isDarkMode, isElementVisible, isEmpty, isMobile, isValidDate, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, pt_br_exports as ptBR, scrollToElement, scrollToPosition, scrollToTop, smoothScrollTo, textToSlug, toISOString, translateStatus, truncateText, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
|
|
796
|
+
//# sourceMappingURL=index.mjs.map
|
|
797
|
+
//# sourceMappingURL=index.mjs.map
|