@rainersoft/utils 1.0.1 → 1.0.3

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
@@ -90,6 +90,52 @@ declare function findMinMax<T extends Record<string, any>>(data: T[], field: key
90
90
  max: number;
91
91
  };
92
92
 
93
+ declare function usePasswordStrength(password: string, options?: {
94
+ minLength?: number;
95
+ requireUppercase?: boolean;
96
+ requireLowercase?: boolean;
97
+ requireNumbers?: boolean;
98
+ requireSpecialChars?: boolean;
99
+ customPatterns?: string[];
100
+ labels?: {
101
+ veryWeak?: string;
102
+ weak?: string;
103
+ fair?: string;
104
+ good?: string;
105
+ strong?: string;
106
+ enterPassword?: string;
107
+ useMinLength?: string;
108
+ addUppercase?: string;
109
+ addLowercase?: string;
110
+ addNumbers?: string;
111
+ addSpecialChars?: string;
112
+ avoidRepeating?: string;
113
+ avoidCommon?: string;
114
+ };
115
+ }): {
116
+ strength: number;
117
+ level: string;
118
+ color: string;
119
+ label: string;
120
+ isValid: boolean;
121
+ validations: {
122
+ hasMinLength: boolean;
123
+ hasUppercase: boolean;
124
+ hasLowercase: boolean;
125
+ hasNumbers: boolean;
126
+ hasSpecialChars: boolean;
127
+ noRepeatingChars: boolean;
128
+ noCommonPatterns: boolean;
129
+ };
130
+ suggestions: string[];
131
+ generateStrongPassword: (length?: number) => string;
132
+ isVeryWeak: boolean;
133
+ isWeak: boolean;
134
+ isFair: boolean;
135
+ isGood: boolean;
136
+ isStrong: boolean;
137
+ };
138
+
93
139
  declare function formatDate(date: string | Date, format?: 'short' | 'long' | 'full'): string;
94
140
  declare function formatDateTime(date: string | Date): string;
95
141
  declare function formatRelativeDate(date: string | Date): string;
@@ -109,4 +155,4 @@ declare namespace ptBr {
109
155
  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 };
110
156
  }
111
157
 
112
- 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, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
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 };
package/dist/index.d.ts CHANGED
@@ -90,6 +90,52 @@ declare function findMinMax<T extends Record<string, any>>(data: T[], field: key
90
90
  max: number;
91
91
  };
92
92
 
93
+ declare function usePasswordStrength(password: string, options?: {
94
+ minLength?: number;
95
+ requireUppercase?: boolean;
96
+ requireLowercase?: boolean;
97
+ requireNumbers?: boolean;
98
+ requireSpecialChars?: boolean;
99
+ customPatterns?: string[];
100
+ labels?: {
101
+ veryWeak?: string;
102
+ weak?: string;
103
+ fair?: string;
104
+ good?: string;
105
+ strong?: string;
106
+ enterPassword?: string;
107
+ useMinLength?: string;
108
+ addUppercase?: string;
109
+ addLowercase?: string;
110
+ addNumbers?: string;
111
+ addSpecialChars?: string;
112
+ avoidRepeating?: string;
113
+ avoidCommon?: string;
114
+ };
115
+ }): {
116
+ strength: number;
117
+ level: string;
118
+ color: string;
119
+ label: string;
120
+ isValid: boolean;
121
+ validations: {
122
+ hasMinLength: boolean;
123
+ hasUppercase: boolean;
124
+ hasLowercase: boolean;
125
+ hasNumbers: boolean;
126
+ hasSpecialChars: boolean;
127
+ noRepeatingChars: boolean;
128
+ noCommonPatterns: boolean;
129
+ };
130
+ suggestions: string[];
131
+ generateStrongPassword: (length?: number) => string;
132
+ isVeryWeak: boolean;
133
+ isWeak: boolean;
134
+ isFair: boolean;
135
+ isGood: boolean;
136
+ isStrong: boolean;
137
+ };
138
+
93
139
  declare function formatDate(date: string | Date, format?: 'short' | 'long' | 'full'): string;
94
140
  declare function formatDateTime(date: string | Date): string;
95
141
  declare function formatRelativeDate(date: string | Date): string;
@@ -109,4 +155,4 @@ declare namespace ptBr {
109
155
  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 };
110
156
  }
111
157
 
112
- 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, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
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 };
package/dist/index.js CHANGED
@@ -1,5 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var React = require('react');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var React__default = /*#__PURE__*/_interopDefault(React);
8
+
3
9
  var __defProp = Object.defineProperty;
4
10
  var __export = (target, all) => {
5
11
  for (var name in all)
@@ -809,6 +815,192 @@ function findMinMax(data, field) {
809
815
  max: Math.max(...values)
810
816
  };
811
817
  }
818
+ function usePasswordStrength(password, options = {}) {
819
+ const {
820
+ minLength = 8,
821
+ requireUppercase = true,
822
+ requireLowercase = true,
823
+ requireNumbers = true,
824
+ requireSpecialChars = true,
825
+ customPatterns = [],
826
+ labels = {}
827
+ } = options;
828
+ const defaultLabels = {
829
+ veryWeak: "Very Weak",
830
+ weak: "Weak",
831
+ fair: "Fair",
832
+ good: "Good",
833
+ strong: "Strong",
834
+ enterPassword: "Enter a password",
835
+ useMinLength: `Use at least ${minLength} characters`,
836
+ addUppercase: "Add uppercase letters",
837
+ addLowercase: "Add lowercase letters",
838
+ addNumbers: "Add numbers",
839
+ addSpecialChars: "Add special characters (!@#$%)",
840
+ avoidRepeating: "Avoid repeating characters",
841
+ avoidCommon: "Avoid common passwords or obvious patterns"
842
+ };
843
+ const finalLabels = { ...defaultLabels, ...labels };
844
+ const strength = React__default.default.useMemo(() => {
845
+ if (!password) return 0;
846
+ let score = 0;
847
+ const length = password.length;
848
+ if (length >= minLength) score += 25;
849
+ if (length >= 12) score += 15;
850
+ if (length >= 16) score += 10;
851
+ if (/[a-z]/.test(password) && requireLowercase) score += 15;
852
+ if (/[A-Z]/.test(password) && requireUppercase) score += 15;
853
+ if (/[0-9]/.test(password) && requireNumbers) score += 15;
854
+ if (/[^a-zA-Z0-9]/.test(password) && requireSpecialChars) score += 20;
855
+ customPatterns.forEach((pattern) => {
856
+ if (new RegExp(pattern).test(password)) {
857
+ score += 5;
858
+ }
859
+ });
860
+ if (/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])/.test(password)) {
861
+ score += 10;
862
+ }
863
+ const commonPatterns = [
864
+ /^123456/,
865
+ /password/i,
866
+ /qwerty/i,
867
+ /admin/i,
868
+ /abc123/i,
869
+ /^(.)\1+$/,
870
+ // Caracteres repetidos
871
+ /^(?:[a-z]+|[A-Z]+|[0-9]+)$/
872
+ // Apenas um tipo de caractere
873
+ ];
874
+ commonPatterns.forEach((pattern) => {
875
+ if (pattern.test(password)) {
876
+ score = Math.max(0, score - 20);
877
+ }
878
+ });
879
+ return Math.min(100, Math.max(0, score));
880
+ }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars, customPatterns]);
881
+ const level = React__default.default.useMemo(() => {
882
+ if (strength < 20) return "very-weak";
883
+ if (strength < 40) return "weak";
884
+ if (strength < 60) return "fair";
885
+ if (strength < 80) return "good";
886
+ return "strong";
887
+ }, [strength]);
888
+ const color = React__default.default.useMemo(() => {
889
+ switch (level) {
890
+ case "very-weak":
891
+ return "#ef4444";
892
+ // red-500
893
+ case "weak":
894
+ return "#f97316";
895
+ // orange-500
896
+ case "fair":
897
+ return "#eab308";
898
+ // yellow-500
899
+ case "good":
900
+ return "#22c55e";
901
+ // green-500
902
+ case "strong":
903
+ return "#059669";
904
+ // emerald-600
905
+ default:
906
+ return "#6b7280";
907
+ }
908
+ }, [level]);
909
+ const label = React__default.default.useMemo(() => {
910
+ switch (level) {
911
+ case "very-weak":
912
+ return finalLabels.veryWeak;
913
+ case "weak":
914
+ return finalLabels.weak;
915
+ case "fair":
916
+ return finalLabels.fair;
917
+ case "good":
918
+ return finalLabels.good;
919
+ case "strong":
920
+ return finalLabels.strong;
921
+ default:
922
+ return finalLabels.enterPassword;
923
+ }
924
+ }, [level, finalLabels]);
925
+ const validations = React__default.default.useMemo(() => {
926
+ return {
927
+ hasMinLength: password.length >= minLength,
928
+ hasUppercase: !requireUppercase || /[A-Z]/.test(password),
929
+ hasLowercase: !requireLowercase || /[a-z]/.test(password),
930
+ hasNumbers: !requireNumbers || /[0-9]/.test(password),
931
+ hasSpecialChars: !requireSpecialChars || /[^a-zA-Z0-9]/.test(password),
932
+ noRepeatingChars: !/^(.)\1+$/.test(password),
933
+ noCommonPatterns: !/123456|password|qwerty|admin|abc123/i.test(password)
934
+ };
935
+ }, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
936
+ const isValid = React__default.default.useMemo(() => {
937
+ return Object.values(validations).every(Boolean);
938
+ }, [validations]);
939
+ const suggestions = React__default.default.useMemo(() => {
940
+ const suggestions2 = [];
941
+ if (!validations.hasMinLength) {
942
+ suggestions2.push(finalLabels.useMinLength);
943
+ }
944
+ if (!validations.hasUppercase && requireUppercase) {
945
+ suggestions2.push(finalLabels.addUppercase);
946
+ }
947
+ if (!validations.hasLowercase && requireLowercase) {
948
+ suggestions2.push(finalLabels.addLowercase);
949
+ }
950
+ if (!validations.hasNumbers && requireNumbers) {
951
+ suggestions2.push(finalLabels.addNumbers);
952
+ }
953
+ if (!validations.hasSpecialChars && requireSpecialChars) {
954
+ suggestions2.push(finalLabels.addSpecialChars);
955
+ }
956
+ if (!validations.noRepeatingChars) {
957
+ suggestions2.push(finalLabels.avoidRepeating);
958
+ }
959
+ if (!validations.noCommonPatterns) {
960
+ suggestions2.push(finalLabels.avoidCommon);
961
+ }
962
+ return suggestions2;
963
+ }, [validations, finalLabels, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
964
+ const generateStrongPassword = React__default.default.useCallback((length = 16) => {
965
+ const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
966
+ const lowercase = "abcdefghijklmnopqrstuvwxyz";
967
+ const numbers = "0123456789";
968
+ const special = "!@#$%^&*()_+-=[]{}|;:,.<>?";
969
+ let chars = lowercase;
970
+ if (requireUppercase) chars += uppercase;
971
+ if (requireNumbers) chars += numbers;
972
+ if (requireSpecialChars) chars += special;
973
+ let password2 = "";
974
+ if (requireLowercase) password2 += lowercase[Math.floor(Math.random() * lowercase.length)];
975
+ if (requireUppercase) password2 += uppercase[Math.floor(Math.random() * uppercase.length)];
976
+ if (requireNumbers) password2 += numbers[Math.floor(Math.random() * numbers.length)];
977
+ if (requireSpecialChars) password2 += special[Math.floor(Math.random() * special.length)];
978
+ for (let i = password2.length; i < length; i++) {
979
+ password2 += chars[Math.floor(Math.random() * chars.length)];
980
+ }
981
+ return password2.split("").sort(() => Math.random() - 0.5).join("");
982
+ }, [requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
983
+ return {
984
+ // Métricas principais
985
+ strength,
986
+ level,
987
+ color,
988
+ label,
989
+ isValid,
990
+ // Validações detalhadas
991
+ validations,
992
+ // Feedback ao usuário
993
+ suggestions,
994
+ // Utilitários
995
+ generateStrongPassword,
996
+ // Estados convenientes
997
+ isVeryWeak: level === "very-weak",
998
+ isWeak: level === "weak",
999
+ isFair: level === "fair",
1000
+ isGood: level === "good",
1001
+ isStrong: level === "strong"
1002
+ };
1003
+ }
812
1004
 
813
1005
  // src/pt-br.ts
814
1006
  var pt_br_exports = {};
@@ -888,6 +1080,7 @@ exports.textToSlug = textToSlug;
888
1080
  exports.toISOString = toISOString;
889
1081
  exports.translateStatus = translateStatus;
890
1082
  exports.truncateText = truncateText;
1083
+ exports.usePasswordStrength = usePasswordStrength;
891
1084
  exports.validateEmail = validateEmail;
892
1085
  exports.validatePassword = validatePassword;
893
1086
  exports.validatePhone = validatePhone;