@cranberry-money/shared-utils 4.6.0 → 4.8.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.ts CHANGED
@@ -11,5 +11,9 @@ export type { BadgeVariant, BadgeSize, BadgeConfig, BadgeStyle } from './badge';
11
11
  export { createBadge, BADGE_VARIANTS, BADGE_SIZES } from './badge';
12
12
  export type { StatusBadgeStyle, TradeStatus, WithdrawalStatus, LiquidationStatus, TargetTradeStatus, } from './badge-status';
13
13
  export { getTradeStatusBadge, getWithdrawalStatusBadge, getLiquidationStatusBadge, getTargetTradeStatusBadge, } from './badge-status';
14
- export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCashAllocation, } from './portfolio';
14
+ export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCashAllocation } from './portfolio';
15
+ export type { LiquidationProgress } from './withdrawal';
16
+ export { formatWithdrawalAmount, formatLiquidationValue, formatSharesQuantity, calculateLiquidationProgress, getTotalEstimatedValue, } from './withdrawal';
17
+ export type { PasswordValidation, EmailConfirmationValidation, ExtendedPasswordValidation } from './validation';
18
+ export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, } from './validation';
15
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGjF,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACrC,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGnE,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGjF,OAAO,EACL,8BAA8B,EAC9B,qCAAqC,EACrC,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGnE,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhH,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,wBAAwB,EACxB,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -13,4 +13,6 @@ export { NUMBER_FORMAT_OPTIONS_CURRENCY, NUMBER_FORMAT_OPTIONS_CURRENCY_SIGNED,
13
13
  export { createBadge, BADGE_VARIANTS, BADGE_SIZES } from './badge';
14
14
  export { getTradeStatusBadge, getWithdrawalStatusBadge, getLiquidationStatusBadge, getTargetTradeStatusBadge, } from './badge-status';
15
15
  // Portfolio utilities
16
- export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCashAllocation, } from './portfolio';
16
+ export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCashAllocation } from './portfolio';
17
+ export { formatWithdrawalAmount, formatLiquidationValue, formatSharesQuantity, calculateLiquidationProgress, getTotalEstimatedValue, } from './withdrawal';
18
+ export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, } from './validation';
@@ -1 +1 @@
1
- {"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../src/portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAItG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIrG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAInG"}
1
+ {"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../src/portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAItG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIrG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAInG"}
package/dist/portfolio.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * allocations, and formatting. All functions handle string or number inputs
6
6
  * for flexibility with API responses.
7
7
  */
8
- import { LOCALE_AUSTRALIA, DEFAULT_NUMERIC_ZERO, DEFAULT_EMPTY_STRING, CURRENCY_AUD } from '@cranberry-money/shared-constants';
8
+ import { LOCALE_AUSTRALIA, DEFAULT_NUMERIC_ZERO, DEFAULT_EMPTY_STRING, CURRENCY_AUD, } from '@cranberry-money/shared-constants';
9
9
  import { NUMBER_FORMAT_OPTIONS_CURRENCY } from './currency';
10
10
  /**
11
11
  * Formats a portfolio value as currency with AUD
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Validation utility functions
3
+ */
4
+ /**
5
+ * Checks if a string contains only numeric characters
6
+ * @param str - The string to validate
7
+ * @returns true if the string contains only digits, false otherwise
8
+ */
9
+ export declare function isNumericOnly(str: string): boolean;
10
+ /**
11
+ * Password validation result interface
12
+ */
13
+ export interface PasswordValidation {
14
+ lengthValid: boolean;
15
+ notNumeric: boolean;
16
+ }
17
+ /**
18
+ * Validates password strength based on minimum requirements
19
+ * @param password - The password to validate
20
+ * @param minLength - Minimum password length (default: 8)
21
+ * @returns An object containing validation results
22
+ */
23
+ export declare function validatePassword(password: string, minLength?: number): PasswordValidation;
24
+ /**
25
+ * Validates if a verification token is in the expected format
26
+ * @param token - The verification token to validate
27
+ * @param minLength - Minimum token length (default: 6)
28
+ * @returns true if token appears to be valid format, false otherwise
29
+ */
30
+ export declare function isValidTokenFormat(token: string, minLength?: number): boolean;
31
+ /**
32
+ * Formats a verification token by removing whitespace and converting to uppercase
33
+ * @param token - The token to format
34
+ * @returns The formatted token
35
+ */
36
+ export declare function formatVerificationToken(token: string): string;
37
+ /**
38
+ * Email confirmation validation result interface
39
+ */
40
+ export interface EmailConfirmationValidation {
41
+ isValid: boolean;
42
+ isEmpty: boolean;
43
+ isValidFormat: boolean;
44
+ }
45
+ /**
46
+ * Validates email confirmation form data
47
+ * @param token - The verification token
48
+ * @param minLength - Minimum token length (default: 6)
49
+ * @returns An object containing validation results
50
+ */
51
+ export declare function validateEmailConfirmation(token: string, minLength?: number): EmailConfirmationValidation;
52
+ /**
53
+ * Validates if an email address is in a valid format
54
+ * @param email - The email address to validate
55
+ * @returns true if email format is valid, false otherwise
56
+ */
57
+ export declare function isValidEmail(email: string): boolean;
58
+ /**
59
+ * Validates if a string contains at least one uppercase letter
60
+ * @param str - The string to validate
61
+ * @returns true if contains uppercase, false otherwise
62
+ */
63
+ export declare function hasUppercase(str: string): boolean;
64
+ /**
65
+ * Validates if a string contains at least one lowercase letter
66
+ * @param str - The string to validate
67
+ * @returns true if contains lowercase, false otherwise
68
+ */
69
+ export declare function hasLowercase(str: string): boolean;
70
+ /**
71
+ * Validates if a string contains at least one special character
72
+ * @param str - The string to validate
73
+ * @returns true if contains special character, false otherwise
74
+ */
75
+ export declare function hasSpecialCharacter(str: string): boolean;
76
+ /**
77
+ * Validates if a string contains at least one digit
78
+ * @param str - The string to validate
79
+ * @returns true if contains digit, false otherwise
80
+ */
81
+ export declare function hasDigit(str: string): boolean;
82
+ /**
83
+ * Extended password validation result interface
84
+ */
85
+ export interface ExtendedPasswordValidation extends PasswordValidation {
86
+ hasUppercase: boolean;
87
+ hasLowercase: boolean;
88
+ hasSpecialCharacter: boolean;
89
+ hasDigit: boolean;
90
+ }
91
+ /**
92
+ * Performs extended password validation with additional strength checks
93
+ * @param password - The password to validate
94
+ * @param minLength - Minimum password length (default: 8)
95
+ * @returns An object containing detailed validation results
96
+ */
97
+ export declare function validatePasswordExtended(password: string, minLength?: number): ExtendedPasswordValidation;
98
+ /**
99
+ * Validates if a phone number is in a valid format
100
+ * @param phoneNumber - The phone number to validate
101
+ * @returns true if phone number format is valid, false otherwise
102
+ */
103
+ export declare function isValidPhoneNumber(phoneNumber: string): boolean;
104
+ /**
105
+ * Validates if a URL is in a valid format
106
+ * @param url - The URL to validate
107
+ * @returns true if URL format is valid, false otherwise
108
+ */
109
+ export declare function isValidUrl(url: string): boolean;
110
+ /**
111
+ * Validates if a date string is in a valid format
112
+ * @param dateString - The date string to validate
113
+ * @returns true if date format is valid, false otherwise
114
+ */
115
+ export declare function isValidDate(dateString: string): boolean;
116
+ /**
117
+ * Validates if a string is empty or contains only whitespace
118
+ * @param str - The string to validate
119
+ * @returns true if string is empty or whitespace only, false otherwise
120
+ */
121
+ export declare function isEmptyOrWhitespace(str: string): boolean;
122
+ /**
123
+ * Validates if a string meets a minimum length requirement
124
+ * @param str - The string to validate
125
+ * @param minLength - The minimum length required
126
+ * @returns true if string meets minimum length, false otherwise
127
+ */
128
+ export declare function meetsMinLength(str: string, minLength: number): boolean;
129
+ /**
130
+ * Validates if a string meets a maximum length requirement
131
+ * @param str - The string to validate
132
+ * @param maxLength - The maximum length allowed
133
+ * @returns true if string meets maximum length, false otherwise
134
+ */
135
+ export declare function meetsMaxLength(str: string, maxLength: number): boolean;
136
+ /**
137
+ * Validates if a number is within a specified range
138
+ * @param value - The number to validate
139
+ * @param min - The minimum value (inclusive)
140
+ * @param max - The maximum value (inclusive)
141
+ * @returns true if number is within range, false otherwise
142
+ */
143
+ export declare function isInRange(value: number, min: number, max: number): boolean;
144
+ /**
145
+ * Validates if a value is a positive number
146
+ * @param value - The value to validate
147
+ * @returns true if value is a positive number, false otherwise
148
+ */
149
+ export declare function isPositiveNumber(value: number): boolean;
150
+ /**
151
+ * Validates if a value is a non-negative number
152
+ * @param value - The value to validate
153
+ * @returns true if value is a non-negative number, false otherwise
154
+ */
155
+ export declare function isNonNegativeNumber(value: number): boolean;
156
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,kBAAkB,CAKpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,OAAO,CAIxE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,2BAA2B,CAQnG;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG,0BAA0B,CAUpG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAK/D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Validation utility functions
3
+ */
4
+ /**
5
+ * Checks if a string contains only numeric characters
6
+ * @param str - The string to validate
7
+ * @returns true if the string contains only digits, false otherwise
8
+ */
9
+ export function isNumericOnly(str) {
10
+ return /^\d+$/.test(str);
11
+ }
12
+ /**
13
+ * Validates password strength based on minimum requirements
14
+ * @param password - The password to validate
15
+ * @param minLength - Minimum password length (default: 8)
16
+ * @returns An object containing validation results
17
+ */
18
+ export function validatePassword(password, minLength = 8) {
19
+ return {
20
+ lengthValid: password.length >= minLength,
21
+ notNumeric: !isNumericOnly(password),
22
+ };
23
+ }
24
+ /**
25
+ * Validates if a verification token is in the expected format
26
+ * @param token - The verification token to validate
27
+ * @param minLength - Minimum token length (default: 6)
28
+ * @returns true if token appears to be valid format, false otherwise
29
+ */
30
+ export function isValidTokenFormat(token, minLength = 6) {
31
+ const trimmedToken = token.trim();
32
+ // Assuming tokens are alphanumeric and meet minimum length
33
+ return trimmedToken.length >= minLength && /^[a-zA-Z0-9]+$/.test(trimmedToken);
34
+ }
35
+ /**
36
+ * Formats a verification token by removing whitespace and converting to uppercase
37
+ * @param token - The token to format
38
+ * @returns The formatted token
39
+ */
40
+ export function formatVerificationToken(token) {
41
+ return token.trim().toUpperCase();
42
+ }
43
+ /**
44
+ * Validates email confirmation form data
45
+ * @param token - The verification token
46
+ * @param minLength - Minimum token length (default: 6)
47
+ * @returns An object containing validation results
48
+ */
49
+ export function validateEmailConfirmation(token, minLength = 6) {
50
+ const formattedToken = formatVerificationToken(token);
51
+ return {
52
+ isValid: formattedToken.length > 0 && isValidTokenFormat(formattedToken, minLength),
53
+ isEmpty: formattedToken.length === 0,
54
+ isValidFormat: isValidTokenFormat(formattedToken, minLength),
55
+ };
56
+ }
57
+ /**
58
+ * Validates if an email address is in a valid format
59
+ * @param email - The email address to validate
60
+ * @returns true if email format is valid, false otherwise
61
+ */
62
+ export function isValidEmail(email) {
63
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
64
+ return emailRegex.test(email.trim());
65
+ }
66
+ /**
67
+ * Validates if a string contains at least one uppercase letter
68
+ * @param str - The string to validate
69
+ * @returns true if contains uppercase, false otherwise
70
+ */
71
+ export function hasUppercase(str) {
72
+ return /[A-Z]/.test(str);
73
+ }
74
+ /**
75
+ * Validates if a string contains at least one lowercase letter
76
+ * @param str - The string to validate
77
+ * @returns true if contains lowercase, false otherwise
78
+ */
79
+ export function hasLowercase(str) {
80
+ return /[a-z]/.test(str);
81
+ }
82
+ /**
83
+ * Validates if a string contains at least one special character
84
+ * @param str - The string to validate
85
+ * @returns true if contains special character, false otherwise
86
+ */
87
+ export function hasSpecialCharacter(str) {
88
+ return /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(str);
89
+ }
90
+ /**
91
+ * Validates if a string contains at least one digit
92
+ * @param str - The string to validate
93
+ * @returns true if contains digit, false otherwise
94
+ */
95
+ export function hasDigit(str) {
96
+ return /\d/.test(str);
97
+ }
98
+ /**
99
+ * Performs extended password validation with additional strength checks
100
+ * @param password - The password to validate
101
+ * @param minLength - Minimum password length (default: 8)
102
+ * @returns An object containing detailed validation results
103
+ */
104
+ export function validatePasswordExtended(password, minLength = 8) {
105
+ const basicValidation = validatePassword(password, minLength);
106
+ return {
107
+ ...basicValidation,
108
+ hasUppercase: hasUppercase(password),
109
+ hasLowercase: hasLowercase(password),
110
+ hasSpecialCharacter: hasSpecialCharacter(password),
111
+ hasDigit: hasDigit(password),
112
+ };
113
+ }
114
+ /**
115
+ * Validates if a phone number is in a valid format
116
+ * @param phoneNumber - The phone number to validate
117
+ * @returns true if phone number format is valid, false otherwise
118
+ */
119
+ export function isValidPhoneNumber(phoneNumber) {
120
+ // Remove common formatting characters
121
+ const cleaned = phoneNumber.replace(/[\s\-\(\)\.]/g, '');
122
+ // Check if it's a valid phone number (digits only, 10-15 digits)
123
+ return /^\+?\d{10,15}$/.test(cleaned);
124
+ }
125
+ /**
126
+ * Validates if a URL is in a valid format
127
+ * @param url - The URL to validate
128
+ * @returns true if URL format is valid, false otherwise
129
+ */
130
+ export function isValidUrl(url) {
131
+ try {
132
+ new URL(url);
133
+ return true;
134
+ }
135
+ catch {
136
+ return false;
137
+ }
138
+ }
139
+ /**
140
+ * Validates if a date string is in a valid format
141
+ * @param dateString - The date string to validate
142
+ * @returns true if date format is valid, false otherwise
143
+ */
144
+ export function isValidDate(dateString) {
145
+ const date = new Date(dateString);
146
+ return !isNaN(date.getTime());
147
+ }
148
+ /**
149
+ * Validates if a string is empty or contains only whitespace
150
+ * @param str - The string to validate
151
+ * @returns true if string is empty or whitespace only, false otherwise
152
+ */
153
+ export function isEmptyOrWhitespace(str) {
154
+ return str.trim().length === 0;
155
+ }
156
+ /**
157
+ * Validates if a string meets a minimum length requirement
158
+ * @param str - The string to validate
159
+ * @param minLength - The minimum length required
160
+ * @returns true if string meets minimum length, false otherwise
161
+ */
162
+ export function meetsMinLength(str, minLength) {
163
+ return str.length >= minLength;
164
+ }
165
+ /**
166
+ * Validates if a string meets a maximum length requirement
167
+ * @param str - The string to validate
168
+ * @param maxLength - The maximum length allowed
169
+ * @returns true if string meets maximum length, false otherwise
170
+ */
171
+ export function meetsMaxLength(str, maxLength) {
172
+ return str.length <= maxLength;
173
+ }
174
+ /**
175
+ * Validates if a number is within a specified range
176
+ * @param value - The number to validate
177
+ * @param min - The minimum value (inclusive)
178
+ * @param max - The maximum value (inclusive)
179
+ * @returns true if number is within range, false otherwise
180
+ */
181
+ export function isInRange(value, min, max) {
182
+ return value >= min && value <= max;
183
+ }
184
+ /**
185
+ * Validates if a value is a positive number
186
+ * @param value - The value to validate
187
+ * @returns true if value is a positive number, false otherwise
188
+ */
189
+ export function isPositiveNumber(value) {
190
+ return typeof value === 'number' && value > 0 && isFinite(value);
191
+ }
192
+ /**
193
+ * Validates if a value is a non-negative number
194
+ * @param value - The value to validate
195
+ * @returns true if value is a non-negative number, false otherwise
196
+ */
197
+ export function isNonNegativeNumber(value) {
198
+ return typeof value === 'number' && value >= 0 && isFinite(value);
199
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Withdrawal-related utility functions
3
+ *
4
+ * This module provides pure functions for formatting withdrawal amounts,
5
+ * calculating liquidation progress, and other withdrawal-related operations.
6
+ * Functions are designed to work with generic types to maintain flexibility.
7
+ */
8
+ /**
9
+ * Formats a withdrawal amount as currency
10
+ *
11
+ * @param amount - Withdrawal amount as string or number
12
+ * @returns Formatted currency string with AUD symbol
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * formatWithdrawalAmount(5000) // 'A$5,000.00'
17
+ * formatWithdrawalAmount('5000.50') // 'A$5,000.50'
18
+ * ```
19
+ */
20
+ export declare function formatWithdrawalAmount(amount: string | number): string;
21
+ /**
22
+ * Formats a liquidation value as currency
23
+ *
24
+ * @param value - Liquidation value as string or number
25
+ * @returns Formatted currency string with AUD symbol
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * formatLiquidationValue(10000) // 'A$10,000.00'
30
+ * formatLiquidationValue('10000.50') // 'A$10,000.50'
31
+ * ```
32
+ */
33
+ export declare function formatLiquidationValue(value: string | number): string;
34
+ /**
35
+ * Formats share quantity without decimal places
36
+ *
37
+ * @param shares - Number of shares
38
+ * @returns Formatted number string with thousands separators
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * formatSharesQuantity(1234) // '1,234'
43
+ * formatSharesQuantity(1234567) // '1,234,567'
44
+ * ```
45
+ */
46
+ export declare function formatSharesQuantity(shares: number): string;
47
+ /**
48
+ * Progress calculation result for liquidations
49
+ */
50
+ export interface LiquidationProgress {
51
+ total: number;
52
+ pending: number;
53
+ inProgress: number;
54
+ completed: number;
55
+ failed: number;
56
+ completionRate: number;
57
+ }
58
+ /**
59
+ * Calculates liquidation progress statistics
60
+ *
61
+ * @param liquidations - Array of liquidation objects with liquidationStatus property
62
+ * @returns Progress statistics including counts and completion rate
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const liquidations = [
67
+ * { liquidationStatus: 'PENDING' },
68
+ * { liquidationStatus: 'SETTLED' },
69
+ * { liquidationStatus: 'FAILED' }
70
+ * ];
71
+ * calculateLiquidationProgress(liquidations)
72
+ * // Returns: { total: 3, pending: 1, inProgress: 0, completed: 1, failed: 1, completionRate: 33.33 }
73
+ * ```
74
+ */
75
+ export declare function calculateLiquidationProgress<T extends {
76
+ liquidationStatus: string;
77
+ }>(liquidations: T[]): LiquidationProgress;
78
+ /**
79
+ * Calculates total estimated value from liquidations
80
+ *
81
+ * @param liquidations - Array of liquidation objects with estimatedValue property
82
+ * @returns Total estimated value as number
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const liquidations = [
87
+ * { estimatedValue: '1000.50' },
88
+ * { estimatedValue: '2000' },
89
+ * { estimatedValue: null }
90
+ * ];
91
+ * getTotalEstimatedValue(liquidations) // 3000.50
92
+ * ```
93
+ */
94
+ export declare function getTotalEstimatedValue<T extends {
95
+ estimatedValue?: string | null;
96
+ }>(liquidations: T[]): number;
97
+ //# sourceMappingURL=withdrawal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withdrawal.d.ts","sourceRoot":"","sources":["../src/withdrawal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,SAAS;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,EAClF,YAAY,EAAE,CAAC,EAAE,GAChB,mBAAmB,CAkBrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS;IAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,MAAM,CAI9G"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Withdrawal-related utility functions
3
+ *
4
+ * This module provides pure functions for formatting withdrawal amounts,
5
+ * calculating liquidation progress, and other withdrawal-related operations.
6
+ * Functions are designed to work with generic types to maintain flexibility.
7
+ */
8
+ import { LOCALE_AUSTRALIA, CURRENCY_AUD, LIQUIDATION_STATUS_PENDING, LIQUIDATION_STATUS_TRADES_CREATED, LIQUIDATION_STATUS_EXECUTED, LIQUIDATION_STATUS_SETTLED, LIQUIDATION_STATUS_FAILED, } from '@cranberry-money/shared-constants';
9
+ import { NUMBER_FORMAT_OPTIONS_CURRENCY } from './currency';
10
+ /**
11
+ * Formats a withdrawal amount as currency
12
+ *
13
+ * @param amount - Withdrawal amount as string or number
14
+ * @returns Formatted currency string with AUD symbol
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * formatWithdrawalAmount(5000) // 'A$5,000.00'
19
+ * formatWithdrawalAmount('5000.50') // 'A$5,000.50'
20
+ * ```
21
+ */
22
+ export function formatWithdrawalAmount(amount) {
23
+ const numValue = typeof amount === 'string' ? parseFloat(amount) : amount;
24
+ return new Intl.NumberFormat(LOCALE_AUSTRALIA, {
25
+ ...NUMBER_FORMAT_OPTIONS_CURRENCY,
26
+ currency: CURRENCY_AUD,
27
+ }).format(numValue);
28
+ }
29
+ /**
30
+ * Formats a liquidation value as currency
31
+ *
32
+ * @param value - Liquidation value as string or number
33
+ * @returns Formatted currency string with AUD symbol
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * formatLiquidationValue(10000) // 'A$10,000.00'
38
+ * formatLiquidationValue('10000.50') // 'A$10,000.50'
39
+ * ```
40
+ */
41
+ export function formatLiquidationValue(value) {
42
+ const numValue = typeof value === 'string' ? parseFloat(value) : value;
43
+ return new Intl.NumberFormat(LOCALE_AUSTRALIA, {
44
+ ...NUMBER_FORMAT_OPTIONS_CURRENCY,
45
+ currency: CURRENCY_AUD,
46
+ }).format(numValue);
47
+ }
48
+ /**
49
+ * Formats share quantity without decimal places
50
+ *
51
+ * @param shares - Number of shares
52
+ * @returns Formatted number string with thousands separators
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * formatSharesQuantity(1234) // '1,234'
57
+ * formatSharesQuantity(1234567) // '1,234,567'
58
+ * ```
59
+ */
60
+ export function formatSharesQuantity(shares) {
61
+ return new Intl.NumberFormat(LOCALE_AUSTRALIA, {
62
+ minimumFractionDigits: 0,
63
+ maximumFractionDigits: 0,
64
+ }).format(shares);
65
+ }
66
+ /**
67
+ * Calculates liquidation progress statistics
68
+ *
69
+ * @param liquidations - Array of liquidation objects with liquidationStatus property
70
+ * @returns Progress statistics including counts and completion rate
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const liquidations = [
75
+ * { liquidationStatus: 'PENDING' },
76
+ * { liquidationStatus: 'SETTLED' },
77
+ * { liquidationStatus: 'FAILED' }
78
+ * ];
79
+ * calculateLiquidationProgress(liquidations)
80
+ * // Returns: { total: 3, pending: 1, inProgress: 0, completed: 1, failed: 1, completionRate: 33.33 }
81
+ * ```
82
+ */
83
+ export function calculateLiquidationProgress(liquidations) {
84
+ const total = liquidations.length;
85
+ const pending = liquidations.filter(l => l.liquidationStatus === LIQUIDATION_STATUS_PENDING).length;
86
+ const inProgress = liquidations.filter(l => [LIQUIDATION_STATUS_TRADES_CREATED, LIQUIDATION_STATUS_EXECUTED].includes(l.liquidationStatus)).length;
87
+ const completed = liquidations.filter(l => l.liquidationStatus === LIQUIDATION_STATUS_SETTLED).length;
88
+ const failed = liquidations.filter(l => l.liquidationStatus === LIQUIDATION_STATUS_FAILED).length;
89
+ const completionRate = total > 0 ? (completed / total) * 100 : 0;
90
+ return {
91
+ total,
92
+ pending,
93
+ inProgress,
94
+ completed,
95
+ failed,
96
+ completionRate,
97
+ };
98
+ }
99
+ /**
100
+ * Calculates total estimated value from liquidations
101
+ *
102
+ * @param liquidations - Array of liquidation objects with estimatedValue property
103
+ * @returns Total estimated value as number
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const liquidations = [
108
+ * { estimatedValue: '1000.50' },
109
+ * { estimatedValue: '2000' },
110
+ * { estimatedValue: null }
111
+ * ];
112
+ * getTotalEstimatedValue(liquidations) // 3000.50
113
+ * ```
114
+ */
115
+ export function getTotalEstimatedValue(liquidations) {
116
+ return liquidations.reduce((total, liquidation) => {
117
+ return total + parseFloat(liquidation.estimatedValue || '0');
118
+ }, 0);
119
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cranberry-money/shared-utils",
3
- "version": "4.6.0",
3
+ "version": "4.8.0",
4
4
  "description": "Shared utility functions for MyPortfolio platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",