@rainersoft/utils 1.0.4 → 1.2.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/dist/index.d.mts CHANGED
@@ -3,7 +3,7 @@ export { C as CURRENCY_MAP, D as DEFAULT_LOCALE, a as LocaleConfig } from './typ
3
3
  export { textToSlug } from './string/index.mjs';
4
4
  export { formatDate, formatDateTime, formatRelativeDate, isValidDate, toISOString } from './date/index.mjs';
5
5
  export { formatCurrency } from './number/index.mjs';
6
- export { GenericStatus, getStatusColor, getStatusVariant, translateStatus } from './status/index.mjs';
6
+ export { GenericStatus, getStatusColor, getStatusVariant, translatePostStatus, translateStatus } from './status/index.mjs';
7
7
 
8
8
  declare function extractInitials(name: string | null | undefined, maxChars?: number): string;
9
9
  declare function generateAvatarUrl(name: string, size?: number, backgroundColor?: string, textColor?: string): string;
@@ -22,6 +22,7 @@ declare function isEmpty(text: string | null | undefined): boolean;
22
22
  declare function normalizeSpaces(text: string, options?: {
23
23
  newlines?: boolean;
24
24
  }): string;
25
+ declare function calculateReadingTime(content: string | Record<string, any>, wordsPerMinute?: number): number;
25
26
 
26
27
  interface ValidationResult {
27
28
  isValid: boolean;
@@ -51,6 +52,10 @@ declare function validateText(text: string, options?: {
51
52
  maxLength?: number;
52
53
  fieldName?: string;
53
54
  }, locale?: Locale): ValidationResult;
55
+ declare function validateMessage(message: string, options?: {
56
+ minLength?: number;
57
+ maxLength?: number;
58
+ }, locale?: Locale): ValidationResult;
54
59
 
55
60
  declare function prefersReducedMotion(): boolean;
56
61
  declare function onReducedMotionChange(callback: (prefersReduced: boolean) => void): () => void;
@@ -90,6 +95,32 @@ declare function findMinMax<T extends Record<string, any>>(data: T[], field: key
90
95
  max: number;
91
96
  };
92
97
 
98
+ declare const getToken: () => string | null;
99
+ declare const setToken: (token: string) => void;
100
+ declare const getRefreshToken: () => string | null;
101
+ declare const setRefreshToken: (refreshToken: string) => void;
102
+ declare const removeToken: () => void;
103
+ declare const hasToken: () => boolean;
104
+ declare const getTokens: () => {
105
+ accessToken: string | null;
106
+ refreshToken: string | null;
107
+ };
108
+ declare const setTokens: ({ accessToken, refreshToken, }: {
109
+ accessToken: string;
110
+ refreshToken: string;
111
+ }) => void;
112
+
113
+ interface SearchOptions {
114
+ fields?: string[];
115
+ caseSensitive?: boolean;
116
+ exactMatch?: boolean;
117
+ }
118
+ declare function searchContent<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions): T[];
119
+ declare function searchWithScore<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions): T[];
120
+ declare function fuzzySearch<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions & {
121
+ threshold?: number;
122
+ }): T[];
123
+
93
124
  declare function usePasswordStrength(password: string, options?: {
94
125
  minLength?: number;
95
126
  requireUppercase?: boolean;
@@ -155,4 +186,4 @@ declare namespace ptBr {
155
186
  export { ptBr_formatCompact as formatCompact, ptBr_formatCurrency as formatCurrency, ptBr_formatDate as formatDate, ptBr_formatDateTime as formatDateTime, ptBr_formatNumber as formatNumber, ptBr_formatRelativeDate as formatRelativeDate, ptBr_translateStatus as translateStatus };
156
187
  }
157
188
 
158
- export { Locale, type ValidationResult, calculateChange, calculateMovingAverage, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatNumber$1 as formatNumber, formatPercentage, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, groupDataByPeriod, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, ptBr as ptBR, scrollToElement, scrollToPosition, scrollToTop, smoothScrollTo, truncateText, usePasswordStrength, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
189
+ export { Locale, type SearchOptions, type ValidationResult, calculateChange, calculateMovingAverage, calculateReadingTime, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatNumber$1 as formatNumber, formatPercentage, fuzzySearch, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, getRefreshToken, getToken, getTokens, groupDataByPeriod, hasToken, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, ptBr as ptBR, removeToken, scrollToElement, scrollToPosition, scrollToTop, searchContent, searchWithScore, setRefreshToken, setToken, setTokens, smoothScrollTo, truncateText, usePasswordStrength, validateEmail, validateMessage, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { C as CURRENCY_MAP, D as DEFAULT_LOCALE, a as LocaleConfig } from './typ
3
3
  export { textToSlug } from './string/index.js';
4
4
  export { formatDate, formatDateTime, formatRelativeDate, isValidDate, toISOString } from './date/index.js';
5
5
  export { formatCurrency } from './number/index.js';
6
- export { GenericStatus, getStatusColor, getStatusVariant, translateStatus } from './status/index.js';
6
+ export { GenericStatus, getStatusColor, getStatusVariant, translatePostStatus, translateStatus } from './status/index.js';
7
7
 
8
8
  declare function extractInitials(name: string | null | undefined, maxChars?: number): string;
9
9
  declare function generateAvatarUrl(name: string, size?: number, backgroundColor?: string, textColor?: string): string;
@@ -22,6 +22,7 @@ declare function isEmpty(text: string | null | undefined): boolean;
22
22
  declare function normalizeSpaces(text: string, options?: {
23
23
  newlines?: boolean;
24
24
  }): string;
25
+ declare function calculateReadingTime(content: string | Record<string, any>, wordsPerMinute?: number): number;
25
26
 
26
27
  interface ValidationResult {
27
28
  isValid: boolean;
@@ -51,6 +52,10 @@ declare function validateText(text: string, options?: {
51
52
  maxLength?: number;
52
53
  fieldName?: string;
53
54
  }, locale?: Locale): ValidationResult;
55
+ declare function validateMessage(message: string, options?: {
56
+ minLength?: number;
57
+ maxLength?: number;
58
+ }, locale?: Locale): ValidationResult;
54
59
 
55
60
  declare function prefersReducedMotion(): boolean;
56
61
  declare function onReducedMotionChange(callback: (prefersReduced: boolean) => void): () => void;
@@ -90,6 +95,32 @@ declare function findMinMax<T extends Record<string, any>>(data: T[], field: key
90
95
  max: number;
91
96
  };
92
97
 
98
+ declare const getToken: () => string | null;
99
+ declare const setToken: (token: string) => void;
100
+ declare const getRefreshToken: () => string | null;
101
+ declare const setRefreshToken: (refreshToken: string) => void;
102
+ declare const removeToken: () => void;
103
+ declare const hasToken: () => boolean;
104
+ declare const getTokens: () => {
105
+ accessToken: string | null;
106
+ refreshToken: string | null;
107
+ };
108
+ declare const setTokens: ({ accessToken, refreshToken, }: {
109
+ accessToken: string;
110
+ refreshToken: string;
111
+ }) => void;
112
+
113
+ interface SearchOptions {
114
+ fields?: string[];
115
+ caseSensitive?: boolean;
116
+ exactMatch?: boolean;
117
+ }
118
+ declare function searchContent<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions): T[];
119
+ declare function searchWithScore<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions): T[];
120
+ declare function fuzzySearch<T extends Record<string, any>>(query: string, content: T[], options?: SearchOptions & {
121
+ threshold?: number;
122
+ }): T[];
123
+
93
124
  declare function usePasswordStrength(password: string, options?: {
94
125
  minLength?: number;
95
126
  requireUppercase?: boolean;
@@ -155,4 +186,4 @@ declare namespace ptBr {
155
186
  export { ptBr_formatCompact as formatCompact, ptBr_formatCurrency as formatCurrency, ptBr_formatDate as formatDate, ptBr_formatDateTime as formatDateTime, ptBr_formatNumber as formatNumber, ptBr_formatRelativeDate as formatRelativeDate, ptBr_translateStatus as translateStatus };
156
187
  }
157
188
 
158
- export { Locale, type ValidationResult, calculateChange, calculateMovingAverage, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatNumber$1 as formatNumber, formatPercentage, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, groupDataByPeriod, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, ptBr as ptBR, scrollToElement, scrollToPosition, scrollToTop, smoothScrollTo, truncateText, usePasswordStrength, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
189
+ export { Locale, type SearchOptions, type ValidationResult, calculateChange, calculateMovingAverage, calculateReadingTime, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatNumber$1 as formatNumber, formatPercentage, fuzzySearch, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, getRefreshToken, getToken, getTokens, groupDataByPeriod, hasToken, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, ptBr as ptBR, removeToken, scrollToElement, scrollToPosition, scrollToTop, searchContent, searchWithScore, setRefreshToken, setToken, setTokens, smoothScrollTo, truncateText, usePasswordStrength, validateEmail, validateMessage, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
package/dist/index.js CHANGED
@@ -125,6 +125,28 @@ function normalizeSpaces(text, options = {}) {
125
125
  }
126
126
  return cleaned.trim();
127
127
  }
128
+ function calculateReadingTime(content, wordsPerMinute = 200) {
129
+ let text = "";
130
+ if (typeof content === "object" && content !== null) {
131
+ const extractText = (node) => {
132
+ if (!node) return "";
133
+ let result = "";
134
+ if (node.text) {
135
+ result += node.text + " ";
136
+ }
137
+ if (Array.isArray(node.content)) {
138
+ result += node.content.map(extractText).join(" ");
139
+ }
140
+ return result;
141
+ };
142
+ text = extractText(content);
143
+ } else if (typeof content === "string") {
144
+ text = content.replace(/<[^>]*>/g, "");
145
+ }
146
+ const words = text.trim().split(/\s+/).filter((word) => word.length > 0).length;
147
+ const time = Math.ceil(words / wordsPerMinute);
148
+ return time > 0 ? time : 1;
149
+ }
128
150
 
129
151
  // src/string/index.ts
130
152
  function textToSlug(text) {
@@ -363,6 +385,25 @@ function getStatusVariant(status) {
363
385
  }
364
386
  return "outline";
365
387
  }
388
+ function translatePostStatus(status, locale = DEFAULT_LOCALE) {
389
+ const postStatusMap = {
390
+ "draft": "DRAFT",
391
+ "published": "PUBLISHED",
392
+ "archived": "ARCHIVED",
393
+ "scheduled": "SCHEDULED",
394
+ "pending_review": "PENDING"
395
+ };
396
+ const normalized = postStatusMap[status.toLowerCase()] || status.toUpperCase();
397
+ if (status.toLowerCase() === "pending_review") {
398
+ const translations = {
399
+ "pt-BR": "Aguardando Revis\xE3o",
400
+ "en-US": "Pending Review",
401
+ "es-ES": "Pendiente de Revisi\xF3n"
402
+ };
403
+ return translations[locale] || translations["pt-BR"];
404
+ }
405
+ return translateStatus(normalized, locale);
406
+ }
366
407
 
367
408
  // src/validation/index.ts
368
409
  function validateEmail(email, locale = DEFAULT_LOCALE) {
@@ -578,6 +619,17 @@ function validateText(text, options = {}, locale = DEFAULT_LOCALE) {
578
619
  errors
579
620
  };
580
621
  }
622
+ function validateMessage(message, options = {}, locale = DEFAULT_LOCALE) {
623
+ const {
624
+ minLength = 10,
625
+ maxLength = 1e3
626
+ } = options;
627
+ return validateText(message, {
628
+ minLength,
629
+ maxLength,
630
+ fieldName: locale === "pt-BR" ? "Mensagem" : locale === "en-US" ? "Message" : "Mensaje"
631
+ }, locale);
632
+ }
581
633
 
582
634
  // src/dom/index.ts
583
635
  function prefersReducedMotion() {
@@ -815,6 +867,142 @@ function findMinMax(data, field) {
815
867
  max: Math.max(...values)
816
868
  };
817
869
  }
870
+
871
+ // src/auth/index.ts
872
+ var TOKEN_KEY = "auth_token";
873
+ var REFRESH_TOKEN_KEY = "refresh_token";
874
+ var getToken = () => {
875
+ if (typeof window === "undefined") {
876
+ return null;
877
+ }
878
+ return localStorage.getItem(TOKEN_KEY);
879
+ };
880
+ var setToken = (token) => {
881
+ if (typeof window === "undefined") {
882
+ return;
883
+ }
884
+ localStorage.setItem(TOKEN_KEY, token);
885
+ };
886
+ var getRefreshToken = () => {
887
+ if (typeof window === "undefined") {
888
+ return null;
889
+ }
890
+ return localStorage.getItem(REFRESH_TOKEN_KEY);
891
+ };
892
+ var setRefreshToken = (refreshToken) => {
893
+ if (typeof window === "undefined") {
894
+ return;
895
+ }
896
+ localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
897
+ };
898
+ var removeToken = () => {
899
+ if (typeof window === "undefined") {
900
+ return;
901
+ }
902
+ localStorage.removeItem(TOKEN_KEY);
903
+ localStorage.removeItem(REFRESH_TOKEN_KEY);
904
+ };
905
+ var hasToken = () => {
906
+ return !!getToken();
907
+ };
908
+ var getTokens = () => {
909
+ return {
910
+ accessToken: getToken(),
911
+ refreshToken: getRefreshToken()
912
+ };
913
+ };
914
+ var setTokens = ({
915
+ accessToken,
916
+ refreshToken
917
+ }) => {
918
+ setToken(accessToken);
919
+ setRefreshToken(refreshToken);
920
+ };
921
+
922
+ // src/search/index.ts
923
+ function searchContent(query, content, options = {}) {
924
+ if (!query.trim()) return content;
925
+ const {
926
+ fields = ["title", "description", "content", "tags"],
927
+ caseSensitive = false,
928
+ exactMatch = false
929
+ } = options;
930
+ const searchQuery = caseSensitive ? query : query.toLowerCase();
931
+ return content.filter((item) => {
932
+ return fields.some((field) => {
933
+ const value = item[field];
934
+ if (!value) return false;
935
+ if (Array.isArray(value)) {
936
+ return value.some((v) => {
937
+ const strValue2 = caseSensitive ? String(v) : String(v).toLowerCase();
938
+ return exactMatch ? strValue2 === searchQuery : strValue2.includes(searchQuery);
939
+ });
940
+ }
941
+ const strValue = caseSensitive ? String(value) : String(value).toLowerCase();
942
+ return exactMatch ? strValue === searchQuery : strValue.includes(searchQuery);
943
+ });
944
+ });
945
+ }
946
+ function searchWithScore(query, content, options = {}) {
947
+ if (!query.trim()) return content;
948
+ const {
949
+ fields = ["title", "description", "content", "tags"],
950
+ caseSensitive = false
951
+ } = options;
952
+ const searchQuery = caseSensitive ? query : query.toLowerCase();
953
+ const scored = content.map((item) => {
954
+ let score = 0;
955
+ fields.forEach((field, index) => {
956
+ const value = item[field];
957
+ if (!value) return;
958
+ const weight = fields.length - index;
959
+ if (Array.isArray(value)) {
960
+ const matches = value.filter((v) => {
961
+ const strValue = caseSensitive ? String(v) : String(v).toLowerCase();
962
+ return strValue.includes(searchQuery);
963
+ }).length;
964
+ score += matches * weight;
965
+ } else {
966
+ const strValue = caseSensitive ? String(value) : String(value).toLowerCase();
967
+ if (strValue.includes(searchQuery)) {
968
+ score += weight;
969
+ if (strValue === searchQuery) {
970
+ score += weight * 2;
971
+ }
972
+ }
973
+ }
974
+ });
975
+ return { item, score };
976
+ });
977
+ return scored.filter(({ score }) => score > 0).sort((a, b) => b.score - a.score).map(({ item }) => item);
978
+ }
979
+ function fuzzySearch(query, content, options = {}) {
980
+ if (!query.trim()) return content;
981
+ const {
982
+ fields = ["title", "description"],
983
+ caseSensitive = false,
984
+ threshold = 0.6
985
+ // Similaridade mínima (0-1)
986
+ } = options;
987
+ const searchQuery = caseSensitive ? query : query.toLowerCase();
988
+ return content.filter((item) => {
989
+ return fields.some((field) => {
990
+ const value = item[field];
991
+ if (!value) return false;
992
+ const strValue = caseSensitive ? String(value) : String(value).toLowerCase();
993
+ const similarity = calculateSimilarity(searchQuery, strValue);
994
+ return similarity >= threshold;
995
+ });
996
+ });
997
+ }
998
+ function calculateSimilarity(str1, str2) {
999
+ if (str1 === str2) return 1;
1000
+ if (str1.length === 0 || str2.length === 0) return 0;
1001
+ if (str2.includes(str1)) return 0.8;
1002
+ const common = str1.split("").filter((char) => str2.includes(char)).length;
1003
+ const similarity = common / Math.max(str1.length, str2.length);
1004
+ return similarity;
1005
+ }
818
1006
  function usePasswordStrength(password, options = {}) {
819
1007
  const {
820
1008
  minLength = 8,
@@ -1039,6 +1227,7 @@ exports.CURRENCY_MAP = CURRENCY_MAP;
1039
1227
  exports.DEFAULT_LOCALE = DEFAULT_LOCALE;
1040
1228
  exports.calculateChange = calculateChange;
1041
1229
  exports.calculateMovingAverage = calculateMovingAverage;
1230
+ exports.calculateReadingTime = calculateReadingTime;
1042
1231
  exports.capitalize = capitalize;
1043
1232
  exports.cleanText = cleanText;
1044
1233
  exports.copyToClipboard = copyToClipboard;
@@ -1052,15 +1241,20 @@ exports.formatDateTime = formatDateTime;
1052
1241
  exports.formatNumber = formatNumber2;
1053
1242
  exports.formatPercentage = formatPercentage;
1054
1243
  exports.formatRelativeDate = formatRelativeDate;
1244
+ exports.fuzzySearch = fuzzySearch;
1055
1245
  exports.generateAvatarUrl = generateAvatarUrl;
1056
1246
  exports.generateDynamicAvatarUrl = generateDynamicAvatarUrl;
1057
1247
  exports.generateMockChartData = generateMockChartData;
1058
1248
  exports.generateUniqueId = generateUniqueId;
1059
1249
  exports.getAvatarColorFromName = getAvatarColorFromName;
1060
1250
  exports.getElementPosition = getElementPosition;
1251
+ exports.getRefreshToken = getRefreshToken;
1061
1252
  exports.getStatusColor = getStatusColor;
1062
1253
  exports.getStatusVariant = getStatusVariant;
1254
+ exports.getToken = getToken;
1255
+ exports.getTokens = getTokens;
1063
1256
  exports.groupDataByPeriod = groupDataByPeriod;
1257
+ exports.hasToken = hasToken;
1064
1258
  exports.isDarkMode = isDarkMode;
1065
1259
  exports.isElementVisible = isElementVisible;
1066
1260
  exports.isEmpty = isEmpty;
@@ -1072,16 +1266,24 @@ exports.onDarkModeChange = onDarkModeChange;
1072
1266
  exports.onReducedMotionChange = onReducedMotionChange;
1073
1267
  exports.prefersReducedMotion = prefersReducedMotion;
1074
1268
  exports.ptBR = pt_br_exports;
1269
+ exports.removeToken = removeToken;
1075
1270
  exports.scrollToElement = scrollToElement;
1076
1271
  exports.scrollToPosition = scrollToPosition;
1077
1272
  exports.scrollToTop = scrollToTop;
1273
+ exports.searchContent = searchContent;
1274
+ exports.searchWithScore = searchWithScore;
1275
+ exports.setRefreshToken = setRefreshToken;
1276
+ exports.setToken = setToken;
1277
+ exports.setTokens = setTokens;
1078
1278
  exports.smoothScrollTo = smoothScrollTo;
1079
1279
  exports.textToSlug = textToSlug;
1080
1280
  exports.toISOString = toISOString;
1281
+ exports.translatePostStatus = translatePostStatus;
1081
1282
  exports.translateStatus = translateStatus;
1082
1283
  exports.truncateText = truncateText;
1083
1284
  exports.usePasswordStrength = usePasswordStrength;
1084
1285
  exports.validateEmail = validateEmail;
1286
+ exports.validateMessage = validateMessage;
1085
1287
  exports.validatePassword = validatePassword;
1086
1288
  exports.validatePhone = validatePhone;
1087
1289
  exports.validateSlug = validateSlug;