@cranberry-money/shared-utils 4.12.0 → 4.14.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/filters.d.ts +56 -0
- package/dist/filters.d.ts.map +1 -1
- package/dist/filters.js +76 -0
- package/dist/formatting.d.ts +59 -0
- package/dist/formatting.d.ts.map +1 -0
- package/dist/formatting.js +81 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/numbers.d.ts +72 -0
- package/dist/numbers.d.ts.map +1 -0
- package/dist/numbers.js +101 -0
- package/dist/validation.d.ts +44 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +62 -0
- package/package.json +1 -1
package/dist/filters.d.ts
CHANGED
|
@@ -62,4 +62,60 @@ export declare function areFiltersEqual<T extends Record<string, unknown>>(filte
|
|
|
62
62
|
* @returns A predicate function that tests if an item matches the filters
|
|
63
63
|
*/
|
|
64
64
|
export declare function createFilterPredicate<T extends Record<string, unknown>, U extends Record<string, unknown>>(filters: T): (item: U) => boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Check if any instrument filters are active (excluding searchQuery)
|
|
67
|
+
* Common pattern for instrument filter checking across applications
|
|
68
|
+
* @param filters - The instrument filter object to check
|
|
69
|
+
* @returns true if any non-search filters are active
|
|
70
|
+
*/
|
|
71
|
+
export declare function hasActiveInstrumentFilters<T extends Record<string, unknown>>(filters: T): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Count active instrument filters (excluding searchQuery)
|
|
74
|
+
* Common pattern for instrument filter counting across applications
|
|
75
|
+
* @param filters - The instrument filter object to count
|
|
76
|
+
* @returns number of active non-search filters
|
|
77
|
+
*/
|
|
78
|
+
export declare function countActiveInstrumentFilters<T extends Record<string, unknown>>(filters: T): number;
|
|
79
|
+
/**
|
|
80
|
+
* Check if any trade filters are active (excluding searchQuery)
|
|
81
|
+
* Common pattern for trade filter checking across applications
|
|
82
|
+
* @param filters - The trade filter object to check
|
|
83
|
+
* @returns true if any non-search filters are active
|
|
84
|
+
*/
|
|
85
|
+
export declare function hasActiveTradeFilters<T extends Record<string, unknown>>(filters: T): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Count active trade filters (excluding searchQuery)
|
|
88
|
+
* Common pattern for trade filter counting across applications
|
|
89
|
+
* @param filters - The trade filter object to count
|
|
90
|
+
* @returns number of active non-search filters
|
|
91
|
+
*/
|
|
92
|
+
export declare function countActiveTradeFilters<T extends Record<string, unknown>>(filters: T): number;
|
|
93
|
+
/**
|
|
94
|
+
* Check if any transaction filters are active (excluding searchQuery)
|
|
95
|
+
* Common pattern for transaction filter checking across applications
|
|
96
|
+
* @param filters - The transaction filter object to check
|
|
97
|
+
* @returns true if any non-search filters are active
|
|
98
|
+
*/
|
|
99
|
+
export declare function hasActiveTransactionFilters<T extends Record<string, unknown>>(filters: T): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Count active transaction filters (excluding searchQuery)
|
|
102
|
+
* Common pattern for transaction filter counting across applications
|
|
103
|
+
* @param filters - The transaction filter object to count
|
|
104
|
+
* @returns number of active non-search filters
|
|
105
|
+
*/
|
|
106
|
+
export declare function countActiveTransactionFilters<T extends Record<string, unknown>>(filters: T): number;
|
|
107
|
+
/**
|
|
108
|
+
* Check if any target trade filters are active (excluding searchQuery)
|
|
109
|
+
* Common pattern for target trade filter checking across applications
|
|
110
|
+
* @param filters - The target trade filter object to check
|
|
111
|
+
* @returns true if any non-search filters are active
|
|
112
|
+
*/
|
|
113
|
+
export declare function hasActiveTargetTradeFilters<T extends Record<string, unknown>>(filters: T): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Count active target trade filters (excluding searchQuery)
|
|
116
|
+
* Common pattern for target trade filter counting across applications
|
|
117
|
+
* @param filters - The target trade filter object to count
|
|
118
|
+
* @returns number of active non-search filters
|
|
119
|
+
*/
|
|
120
|
+
export declare function countActiveTargetTradeFilters<T extends Record<string, unknown>>(filters: T): number;
|
|
65
121
|
//# sourceMappingURL=filters.d.ts.map
|
package/dist/filters.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../src/filters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,OAAO,EAAE,CAAC,EACV,aAAa,GAAE,CAAC,MAAM,CAAC,CAAC,EAA+B,GACtD,OAAO,CAOT;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,OAAO,EAAE,CAAC,EACV,aAAa,GAAE,CAAC,MAAM,CAAC,CAAC,EAA+B,GACtD,MAAM,CAOR;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,OAAO,EAAE,CAAC,EACV,cAAc,GAAE,CAAC,MAAM,CAAC,CAAC,EAAO,GAC/B,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAE1G;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAW5F;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAE9G;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAkBpG;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxG,OAAO,EAAE,CAAC,GACT,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAuBtB"}
|
|
1
|
+
{"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../src/filters.ts"],"names":[],"mappings":"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"}
|
package/dist/filters.js
CHANGED
|
@@ -128,3 +128,79 @@ export function createFilterPredicate(filters) {
|
|
|
128
128
|
});
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Common Filter Patterns
|
|
133
|
+
// Pre-configured utilities for common filter use cases
|
|
134
|
+
// ============================================================================
|
|
135
|
+
/**
|
|
136
|
+
* Check if any instrument filters are active (excluding searchQuery)
|
|
137
|
+
* Common pattern for instrument filter checking across applications
|
|
138
|
+
* @param filters - The instrument filter object to check
|
|
139
|
+
* @returns true if any non-search filters are active
|
|
140
|
+
*/
|
|
141
|
+
export function hasActiveInstrumentFilters(filters) {
|
|
142
|
+
return hasActiveFilters(filters, ['searchQuery']);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Count active instrument filters (excluding searchQuery)
|
|
146
|
+
* Common pattern for instrument filter counting across applications
|
|
147
|
+
* @param filters - The instrument filter object to count
|
|
148
|
+
* @returns number of active non-search filters
|
|
149
|
+
*/
|
|
150
|
+
export function countActiveInstrumentFilters(filters) {
|
|
151
|
+
return countActiveFilters(filters, ['searchQuery']);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check if any trade filters are active (excluding searchQuery)
|
|
155
|
+
* Common pattern for trade filter checking across applications
|
|
156
|
+
* @param filters - The trade filter object to check
|
|
157
|
+
* @returns true if any non-search filters are active
|
|
158
|
+
*/
|
|
159
|
+
export function hasActiveTradeFilters(filters) {
|
|
160
|
+
return hasActiveFilters(filters, ['searchQuery']);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Count active trade filters (excluding searchQuery)
|
|
164
|
+
* Common pattern for trade filter counting across applications
|
|
165
|
+
* @param filters - The trade filter object to count
|
|
166
|
+
* @returns number of active non-search filters
|
|
167
|
+
*/
|
|
168
|
+
export function countActiveTradeFilters(filters) {
|
|
169
|
+
return countActiveFilters(filters, ['searchQuery']);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if any transaction filters are active (excluding searchQuery)
|
|
173
|
+
* Common pattern for transaction filter checking across applications
|
|
174
|
+
* @param filters - The transaction filter object to check
|
|
175
|
+
* @returns true if any non-search filters are active
|
|
176
|
+
*/
|
|
177
|
+
export function hasActiveTransactionFilters(filters) {
|
|
178
|
+
return hasActiveFilters(filters, ['searchQuery']);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Count active transaction filters (excluding searchQuery)
|
|
182
|
+
* Common pattern for transaction filter counting across applications
|
|
183
|
+
* @param filters - The transaction filter object to count
|
|
184
|
+
* @returns number of active non-search filters
|
|
185
|
+
*/
|
|
186
|
+
export function countActiveTransactionFilters(filters) {
|
|
187
|
+
return countActiveFilters(filters, ['searchQuery']);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check if any target trade filters are active (excluding searchQuery)
|
|
191
|
+
* Common pattern for target trade filter checking across applications
|
|
192
|
+
* @param filters - The target trade filter object to check
|
|
193
|
+
* @returns true if any non-search filters are active
|
|
194
|
+
*/
|
|
195
|
+
export function hasActiveTargetTradeFilters(filters) {
|
|
196
|
+
return hasActiveFilters(filters, ['searchQuery']);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Count active target trade filters (excluding searchQuery)
|
|
200
|
+
* Common pattern for target trade filter counting across applications
|
|
201
|
+
* @param filters - The target trade filter object to count
|
|
202
|
+
* @returns number of active non-search filters
|
|
203
|
+
*/
|
|
204
|
+
export function countActiveTargetTradeFilters(filters) {
|
|
205
|
+
return countActiveFilters(filters, ['searchQuery']);
|
|
206
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String formatting utilities
|
|
3
|
+
* Generic string manipulation and formatting functions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Capitalize the first letter of a string and make the rest lowercase
|
|
7
|
+
* @param str - The string to capitalize
|
|
8
|
+
* @returns Capitalized string
|
|
9
|
+
* @example
|
|
10
|
+
* capitalizeFirstLetter('HELLO WORLD') // 'Hello world'
|
|
11
|
+
* capitalizeFirstLetter('low') // 'Low'
|
|
12
|
+
*/
|
|
13
|
+
export declare function capitalizeFirstLetter(str: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Format a status string for display (capitalize first letter, lowercase rest)
|
|
16
|
+
* @param status - The status string to format
|
|
17
|
+
* @returns Formatted status string
|
|
18
|
+
* @example
|
|
19
|
+
* formatStatus('PENDING') // 'Pending'
|
|
20
|
+
* formatStatus('completed') // 'Completed'
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatStatus(status: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Format a risk level string for display (capitalize first letter, lowercase rest)
|
|
25
|
+
* @param riskLevel - The risk level string to format
|
|
26
|
+
* @returns Formatted risk level string
|
|
27
|
+
* @example
|
|
28
|
+
* formatRiskLevel('HIGH') // 'High'
|
|
29
|
+
* formatRiskLevel('moderate') // 'Moderate'
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatRiskLevel(riskLevel: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Capitalize only the first letter, keeping the rest unchanged
|
|
34
|
+
* @param str - The string to capitalize
|
|
35
|
+
* @returns String with first letter capitalized
|
|
36
|
+
* @example
|
|
37
|
+
* capitalizeFirst('hello World') // 'Hello World'
|
|
38
|
+
* capitalizeFirst('iPhone') // 'IPhone'
|
|
39
|
+
*/
|
|
40
|
+
export declare function capitalizeFirst(str: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Format a label by replacing underscores with spaces and capitalizing
|
|
43
|
+
* @param label - The label to format
|
|
44
|
+
* @returns Formatted label
|
|
45
|
+
* @example
|
|
46
|
+
* formatLabel('first_name') // 'First name'
|
|
47
|
+
* formatLabel('user_profile_data') // 'User profile data'
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatLabel(label: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Convert camelCase to Title Case
|
|
52
|
+
* @param str - The camelCase string to convert
|
|
53
|
+
* @returns Title Case string
|
|
54
|
+
* @example
|
|
55
|
+
* camelToTitle('firstName') // 'First Name'
|
|
56
|
+
* camelToTitle('userProfileData') // 'User Profile Data'
|
|
57
|
+
*/
|
|
58
|
+
export declare function camelToTitle(str: string): string;
|
|
59
|
+
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../src/formatting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String formatting utilities
|
|
3
|
+
* Generic string manipulation and formatting functions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Capitalize the first letter of a string and make the rest lowercase
|
|
7
|
+
* @param str - The string to capitalize
|
|
8
|
+
* @returns Capitalized string
|
|
9
|
+
* @example
|
|
10
|
+
* capitalizeFirstLetter('HELLO WORLD') // 'Hello world'
|
|
11
|
+
* capitalizeFirstLetter('low') // 'Low'
|
|
12
|
+
*/
|
|
13
|
+
export function capitalizeFirstLetter(str) {
|
|
14
|
+
if (!str)
|
|
15
|
+
return str;
|
|
16
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Format a status string for display (capitalize first letter, lowercase rest)
|
|
20
|
+
* @param status - The status string to format
|
|
21
|
+
* @returns Formatted status string
|
|
22
|
+
* @example
|
|
23
|
+
* formatStatus('PENDING') // 'Pending'
|
|
24
|
+
* formatStatus('completed') // 'Completed'
|
|
25
|
+
*/
|
|
26
|
+
export function formatStatus(status) {
|
|
27
|
+
return capitalizeFirstLetter(status);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Format a risk level string for display (capitalize first letter, lowercase rest)
|
|
31
|
+
* @param riskLevel - The risk level string to format
|
|
32
|
+
* @returns Formatted risk level string
|
|
33
|
+
* @example
|
|
34
|
+
* formatRiskLevel('HIGH') // 'High'
|
|
35
|
+
* formatRiskLevel('moderate') // 'Moderate'
|
|
36
|
+
*/
|
|
37
|
+
export function formatRiskLevel(riskLevel) {
|
|
38
|
+
return capitalizeFirstLetter(riskLevel);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Capitalize only the first letter, keeping the rest unchanged
|
|
42
|
+
* @param str - The string to capitalize
|
|
43
|
+
* @returns String with first letter capitalized
|
|
44
|
+
* @example
|
|
45
|
+
* capitalizeFirst('hello World') // 'Hello World'
|
|
46
|
+
* capitalizeFirst('iPhone') // 'IPhone'
|
|
47
|
+
*/
|
|
48
|
+
export function capitalizeFirst(str) {
|
|
49
|
+
if (!str)
|
|
50
|
+
return str;
|
|
51
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Format a label by replacing underscores with spaces and capitalizing
|
|
55
|
+
* @param label - The label to format
|
|
56
|
+
* @returns Formatted label
|
|
57
|
+
* @example
|
|
58
|
+
* formatLabel('first_name') // 'First name'
|
|
59
|
+
* formatLabel('user_profile_data') // 'User profile data'
|
|
60
|
+
*/
|
|
61
|
+
export function formatLabel(label) {
|
|
62
|
+
if (!label)
|
|
63
|
+
return label;
|
|
64
|
+
return capitalizeFirstLetter(label.replace(/_/g, ' '));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Convert camelCase to Title Case
|
|
68
|
+
* @param str - The camelCase string to convert
|
|
69
|
+
* @returns Title Case string
|
|
70
|
+
* @example
|
|
71
|
+
* camelToTitle('firstName') // 'First Name'
|
|
72
|
+
* camelToTitle('userProfileData') // 'User Profile Data'
|
|
73
|
+
*/
|
|
74
|
+
export function camelToTitle(str) {
|
|
75
|
+
if (!str)
|
|
76
|
+
return str;
|
|
77
|
+
return str
|
|
78
|
+
.replace(/([A-Z])/g, ' $1')
|
|
79
|
+
.replace(/^./, match => match.toUpperCase())
|
|
80
|
+
.trim();
|
|
81
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,12 +15,14 @@ export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCash
|
|
|
15
15
|
export type { LiquidationProgress } from './withdrawal';
|
|
16
16
|
export { formatWithdrawalAmount, formatLiquidationValue, formatSharesQuantity, calculateLiquidationProgress, getTotalEstimatedValue, } from './withdrawal';
|
|
17
17
|
export type { PasswordValidation, EmailConfirmationValidation, ExtendedPasswordValidation } from './validation';
|
|
18
|
-
export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidPhoneFormat, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, isValidFullName, isValidDateOfBirth, formatPhoneNumber, isValidInvestmentAmount, hasMinimumSelection, isSelected, } from './validation';
|
|
19
|
-
export { hasActiveFilters, countActiveFilters, clearAllFilters, updateFilters, isFilterEmpty, removeEmptyFilters, mergeFilters, areFiltersEqual, createFilterPredicate, } from './filters';
|
|
18
|
+
export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidPhoneFormat, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, isValidFullName, isValidDateOfBirth, formatPhoneNumber, isValidInvestmentAmount, hasMinimumSelection, isSelected, validatePercentageSum, validateAllocationSum, isInNumberRange, isValidPercentage, } from './validation';
|
|
19
|
+
export { hasActiveFilters, countActiveFilters, clearAllFilters, updateFilters, isFilterEmpty, removeEmptyFilters, mergeFilters, areFiltersEqual, createFilterPredicate, hasActiveInstrumentFilters, countActiveInstrumentFilters, hasActiveTradeFilters, countActiveTradeFilters, hasActiveTransactionFilters, countActiveTransactionFilters, hasActiveTargetTradeFilters, countActiveTargetTradeFilters, } from './filters';
|
|
20
20
|
export type { DeviceInfo, TokenRefreshResponse, TokenRefreshError, AutoRefreshHandler } from './auth';
|
|
21
21
|
export { isTokenExpired, isTokenExpiringSoon, getTimeUntilExpiry, formatTimeUntilExpiry, parseDeviceInfo, isRefreshSuccess, getRefreshErrorMessage, createAutoRefreshHandler, } from './auth';
|
|
22
22
|
export type { InstrumentTypeInfo, InstrumentBasicInfo, PriceChangeResult, PriceSnapshot, FormattedPriceChange, TradeableInstrument, MarketDataInfo, } from './instruments';
|
|
23
23
|
export { formatInstrumentPrice, getCurrencySymbol, getInstrumentType, formatInstrumentName, calculatePriceChange, formatPriceChange, isInstrumentTradeable, formatMarketCap, formatVolume, hasMarketData, } from './instruments';
|
|
24
24
|
export { sortByStringField, filterByTextSearch, filterByBooleanField, findByField, findByStringField, extractAndSortField, groupByFirstLetter, groupByField, hasItemWithFieldValue, countByFieldValue, } from './collections';
|
|
25
25
|
export { downloadBlob, downloadTextFile, downloadJsonFile, generateTimestampedFilename, downloadDataUrl, downloadCsvFile, } from './downloads';
|
|
26
|
+
export { capitalizeFirstLetter, formatStatus, formatRiskLevel, capitalizeFirst, formatLabel, camelToTitle, } from './formatting';
|
|
27
|
+
export { formatQuantityWithSuffix, formatLargeNumber, formatAsPercentage, formatWithSeparators, roundToDecimals, clampNumber, } from './numbers';
|
|
26
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,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,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,12 +15,20 @@ export { getTradeStatusBadge, getWithdrawalStatusBadge, getLiquidationStatusBadg
|
|
|
15
15
|
// Portfolio utilities
|
|
16
16
|
export { formatPortfolioValue, calculateTotalValue, getMarketAllocation, getCashAllocation } from './portfolio';
|
|
17
17
|
export { formatWithdrawalAmount, formatLiquidationValue, formatSharesQuantity, calculateLiquidationProgress, getTotalEstimatedValue, } from './withdrawal';
|
|
18
|
-
export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidPhoneFormat, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, isValidFullName, isValidDateOfBirth, formatPhoneNumber, isValidInvestmentAmount, hasMinimumSelection, isSelected,
|
|
18
|
+
export { isNumericOnly, validatePassword, isValidTokenFormat, formatVerificationToken, validateEmailConfirmation, isValidEmail, hasUppercase, hasLowercase, hasSpecialCharacter, hasDigit, validatePasswordExtended, isValidPhoneNumber, isValidPhoneFormat, isValidUrl, isValidDate, isEmptyOrWhitespace, meetsMinLength, meetsMaxLength, isInRange, isPositiveNumber, isNonNegativeNumber, isValidFullName, isValidDateOfBirth, formatPhoneNumber, isValidInvestmentAmount, hasMinimumSelection, isSelected,
|
|
19
|
+
// Enhanced validation utilities (Phase 14)
|
|
20
|
+
validatePercentageSum, validateAllocationSum, isInNumberRange, isValidPercentage, } from './validation';
|
|
19
21
|
// Filter utilities
|
|
20
|
-
export { hasActiveFilters, countActiveFilters, clearAllFilters, updateFilters, isFilterEmpty, removeEmptyFilters, mergeFilters, areFiltersEqual, createFilterPredicate,
|
|
22
|
+
export { hasActiveFilters, countActiveFilters, clearAllFilters, updateFilters, isFilterEmpty, removeEmptyFilters, mergeFilters, areFiltersEqual, createFilterPredicate,
|
|
23
|
+
// Common filter patterns
|
|
24
|
+
hasActiveInstrumentFilters, countActiveInstrumentFilters, hasActiveTradeFilters, countActiveTradeFilters, hasActiveTransactionFilters, countActiveTransactionFilters, hasActiveTargetTradeFilters, countActiveTargetTradeFilters, } from './filters';
|
|
21
25
|
export { isTokenExpired, isTokenExpiringSoon, getTimeUntilExpiry, formatTimeUntilExpiry, parseDeviceInfo, isRefreshSuccess, getRefreshErrorMessage, createAutoRefreshHandler, } from './auth';
|
|
22
26
|
export { formatInstrumentPrice, getCurrencySymbol, getInstrumentType, formatInstrumentName, calculatePriceChange, formatPriceChange, isInstrumentTradeable, formatMarketCap, formatVolume, hasMarketData, } from './instruments';
|
|
23
27
|
// Collection utilities
|
|
24
28
|
export { sortByStringField, filterByTextSearch, filterByBooleanField, findByField, findByStringField, extractAndSortField, groupByFirstLetter, groupByField, hasItemWithFieldValue, countByFieldValue, } from './collections';
|
|
25
29
|
// Download utilities
|
|
26
30
|
export { downloadBlob, downloadTextFile, downloadJsonFile, generateTimestampedFilename, downloadDataUrl, downloadCsvFile, } from './downloads';
|
|
31
|
+
// String formatting utilities
|
|
32
|
+
export { capitalizeFirstLetter, formatStatus, formatRiskLevel, capitalizeFirst, formatLabel, camelToTitle, } from './formatting';
|
|
33
|
+
// Number formatting utilities
|
|
34
|
+
export { formatQuantityWithSuffix, formatLargeNumber, formatAsPercentage, formatWithSeparators, roundToDecimals, clampNumber, } from './numbers';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number formatting utilities
|
|
3
|
+
* Generic number manipulation and formatting functions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Format a large number with K/M suffixes for display
|
|
7
|
+
* @param quantity - The number to format
|
|
8
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
9
|
+
* @returns Formatted number string with suffix
|
|
10
|
+
* @example
|
|
11
|
+
* formatQuantityWithSuffix(1000) // '1.0K'
|
|
12
|
+
* formatQuantityWithSuffix(1500000) // '1.5M'
|
|
13
|
+
* formatQuantityWithSuffix(999) // '999'
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatQuantityWithSuffix(quantity: number, decimals?: number): string;
|
|
16
|
+
/**
|
|
17
|
+
* Format a large number with customizable suffixes
|
|
18
|
+
* @param num - The number to format
|
|
19
|
+
* @param suffixes - Array of suffix configurations (default: standard K, M, B, T)
|
|
20
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
21
|
+
* @returns Formatted number string with suffix
|
|
22
|
+
* @example
|
|
23
|
+
* formatLargeNumber(1500000) // '1.5M'
|
|
24
|
+
* formatLargeNumber(1500000000) // '1.5B'
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatLargeNumber(num: number, suffixes?: Array<{
|
|
27
|
+
threshold: number;
|
|
28
|
+
suffix: string;
|
|
29
|
+
}>, decimals?: number): string;
|
|
30
|
+
/**
|
|
31
|
+
* Format a number as a percentage
|
|
32
|
+
* @param value - The decimal value to format as percentage
|
|
33
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
34
|
+
* @returns Formatted percentage string
|
|
35
|
+
* @example
|
|
36
|
+
* formatAsPercentage(0.1234) // '12.3%'
|
|
37
|
+
* formatAsPercentage(0.5, 0) // '50%'
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatAsPercentage(value: number, decimals?: number): string;
|
|
40
|
+
/**
|
|
41
|
+
* Format a number with thousand separators
|
|
42
|
+
* @param num - The number to format
|
|
43
|
+
* @param separator - The separator character (default: ',')
|
|
44
|
+
* @returns Formatted number string with separators
|
|
45
|
+
* @example
|
|
46
|
+
* formatWithSeparators(1234567) // '1,234,567'
|
|
47
|
+
* formatWithSeparators(1234567, ' ') // '1 234 567'
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatWithSeparators(num: number, separator?: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Round a number to specified decimal places
|
|
52
|
+
* @param num - The number to round
|
|
53
|
+
* @param decimals - Number of decimal places (default: 2)
|
|
54
|
+
* @returns Rounded number
|
|
55
|
+
* @example
|
|
56
|
+
* roundToDecimals(3.14159, 2) // 3.14
|
|
57
|
+
* roundToDecimals(123.456, 0) // 123
|
|
58
|
+
*/
|
|
59
|
+
export declare function roundToDecimals(num: number, decimals?: number): number;
|
|
60
|
+
/**
|
|
61
|
+
* Clamp a number between min and max values
|
|
62
|
+
* @param num - The number to clamp
|
|
63
|
+
* @param min - Minimum value
|
|
64
|
+
* @param max - Maximum value
|
|
65
|
+
* @returns Clamped number
|
|
66
|
+
* @example
|
|
67
|
+
* clampNumber(150, 0, 100) // 100
|
|
68
|
+
* clampNumber(-10, 0, 100) // 0
|
|
69
|
+
* clampNumber(50, 0, 100) // 50
|
|
70
|
+
*/
|
|
71
|
+
export declare function clampNumber(num: number, min: number, max: number): number;
|
|
72
|
+
//# sourceMappingURL=numbers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbers.d.ts","sourceRoot":"","sources":["../src/numbers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,CAWvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKpD,EACD,QAAQ,GAAE,MAAU,GACnB,MAAM,CAOR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,CAE9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAEjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,CAGzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzE"}
|
package/dist/numbers.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number formatting utilities
|
|
3
|
+
* Generic number manipulation and formatting functions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Format a large number with K/M suffixes for display
|
|
7
|
+
* @param quantity - The number to format
|
|
8
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
9
|
+
* @returns Formatted number string with suffix
|
|
10
|
+
* @example
|
|
11
|
+
* formatQuantityWithSuffix(1000) // '1.0K'
|
|
12
|
+
* formatQuantityWithSuffix(1500000) // '1.5M'
|
|
13
|
+
* formatQuantityWithSuffix(999) // '999'
|
|
14
|
+
*/
|
|
15
|
+
export function formatQuantityWithSuffix(quantity, decimals = 1) {
|
|
16
|
+
const million = 1000000;
|
|
17
|
+
const thousand = 1000;
|
|
18
|
+
if (quantity >= million) {
|
|
19
|
+
return `${(quantity / million).toFixed(decimals)}M`;
|
|
20
|
+
}
|
|
21
|
+
else if (quantity >= thousand) {
|
|
22
|
+
return `${(quantity / thousand).toFixed(decimals)}K`;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return quantity.toString();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Format a large number with customizable suffixes
|
|
30
|
+
* @param num - The number to format
|
|
31
|
+
* @param suffixes - Array of suffix configurations (default: standard K, M, B, T)
|
|
32
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
33
|
+
* @returns Formatted number string with suffix
|
|
34
|
+
* @example
|
|
35
|
+
* formatLargeNumber(1500000) // '1.5M'
|
|
36
|
+
* formatLargeNumber(1500000000) // '1.5B'
|
|
37
|
+
*/
|
|
38
|
+
export function formatLargeNumber(num, suffixes = [
|
|
39
|
+
{ threshold: 1000000000000, suffix: 'T' },
|
|
40
|
+
{ threshold: 1000000000, suffix: 'B' },
|
|
41
|
+
{ threshold: 1000000, suffix: 'M' },
|
|
42
|
+
{ threshold: 1000, suffix: 'K' },
|
|
43
|
+
], decimals = 1) {
|
|
44
|
+
for (const { threshold, suffix } of suffixes) {
|
|
45
|
+
if (num >= threshold) {
|
|
46
|
+
return `${(num / threshold).toFixed(decimals)}${suffix}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return num.toString();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Format a number as a percentage
|
|
53
|
+
* @param value - The decimal value to format as percentage
|
|
54
|
+
* @param decimals - Number of decimal places (default: 1)
|
|
55
|
+
* @returns Formatted percentage string
|
|
56
|
+
* @example
|
|
57
|
+
* formatAsPercentage(0.1234) // '12.3%'
|
|
58
|
+
* formatAsPercentage(0.5, 0) // '50%'
|
|
59
|
+
*/
|
|
60
|
+
export function formatAsPercentage(value, decimals = 1) {
|
|
61
|
+
return `${(value * 100).toFixed(decimals)}%`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Format a number with thousand separators
|
|
65
|
+
* @param num - The number to format
|
|
66
|
+
* @param separator - The separator character (default: ',')
|
|
67
|
+
* @returns Formatted number string with separators
|
|
68
|
+
* @example
|
|
69
|
+
* formatWithSeparators(1234567) // '1,234,567'
|
|
70
|
+
* formatWithSeparators(1234567, ' ') // '1 234 567'
|
|
71
|
+
*/
|
|
72
|
+
export function formatWithSeparators(num, separator = ',') {
|
|
73
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Round a number to specified decimal places
|
|
77
|
+
* @param num - The number to round
|
|
78
|
+
* @param decimals - Number of decimal places (default: 2)
|
|
79
|
+
* @returns Rounded number
|
|
80
|
+
* @example
|
|
81
|
+
* roundToDecimals(3.14159, 2) // 3.14
|
|
82
|
+
* roundToDecimals(123.456, 0) // 123
|
|
83
|
+
*/
|
|
84
|
+
export function roundToDecimals(num, decimals = 2) {
|
|
85
|
+
const factor = Math.pow(10, decimals);
|
|
86
|
+
return Math.round(num * factor) / factor;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Clamp a number between min and max values
|
|
90
|
+
* @param num - The number to clamp
|
|
91
|
+
* @param min - Minimum value
|
|
92
|
+
* @param max - Maximum value
|
|
93
|
+
* @returns Clamped number
|
|
94
|
+
* @example
|
|
95
|
+
* clampNumber(150, 0, 100) // 100
|
|
96
|
+
* clampNumber(-10, 0, 100) // 0
|
|
97
|
+
* clampNumber(50, 0, 100) // 50
|
|
98
|
+
*/
|
|
99
|
+
export function clampNumber(num, min, max) {
|
|
100
|
+
return Math.min(Math.max(num, min), max);
|
|
101
|
+
}
|
package/dist/validation.d.ts
CHANGED
|
@@ -202,4 +202,48 @@ export declare function hasMinimumSelection<T>(items: T[], minItems?: number): b
|
|
|
202
202
|
* @returns true if value is selected, false otherwise
|
|
203
203
|
*/
|
|
204
204
|
export declare function isSelected(value: unknown): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Validates that percentage values sum to a target value (default 100)
|
|
207
|
+
* @param values - Array of percentage values
|
|
208
|
+
* @param target - Target sum value (default: 100)
|
|
209
|
+
* @param tolerance - Allowed tolerance for floating point differences (default: 0.01)
|
|
210
|
+
* @returns true if sum equals target within tolerance, false otherwise
|
|
211
|
+
* @example
|
|
212
|
+
* validatePercentageSum([25, 25, 50]) // true (sums to 100)
|
|
213
|
+
* validatePercentageSum([33.33, 33.33, 33.34]) // true (within tolerance)
|
|
214
|
+
* validatePercentageSum([50, 30, 15]) // false (sums to 95)
|
|
215
|
+
*/
|
|
216
|
+
export declare function validatePercentageSum(values: number[], target?: number, tolerance?: number): boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Validates that allocation objects with percentage properties sum to 100%
|
|
219
|
+
* @param allocations - Array of objects with percentage property
|
|
220
|
+
* @param percentageField - Name of the percentage field (default: 'percentage')
|
|
221
|
+
* @param tolerance - Allowed tolerance for floating point differences (default: 0.01)
|
|
222
|
+
* @returns true if sum equals 100 within tolerance, false otherwise
|
|
223
|
+
* @example
|
|
224
|
+
* validateAllocationSum([{percentage: 50}, {percentage: 50}]) // true
|
|
225
|
+
* validateAllocationSum([{percentage: '33.33'}, {percentage: '66.67'}]) // true
|
|
226
|
+
*/
|
|
227
|
+
export declare function validateAllocationSum<T extends Record<string, unknown>>(allocations: T[], percentageField?: keyof T, tolerance?: number): boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Validates that a number is within a specified range (inclusive)
|
|
230
|
+
* @param value - The number to validate
|
|
231
|
+
* @param min - Minimum allowed value
|
|
232
|
+
* @param max - Maximum allowed value
|
|
233
|
+
* @returns true if number is within range, false otherwise
|
|
234
|
+
* @example
|
|
235
|
+
* isInNumberRange(50, 0, 100) // true
|
|
236
|
+
* isInNumberRange(150, 0, 100) // false
|
|
237
|
+
*/
|
|
238
|
+
export declare function isInNumberRange(value: number, min: number, max: number): boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Validates that a percentage is between 0 and 100
|
|
241
|
+
* @param percentage - The percentage to validate
|
|
242
|
+
* @returns true if valid percentage, false otherwise
|
|
243
|
+
* @example
|
|
244
|
+
* isValidPercentage(50) // true
|
|
245
|
+
* isValidPercentage(150) // false
|
|
246
|
+
* isValidPercentage(-10) // false
|
|
247
|
+
*/
|
|
248
|
+
export declare function isValidPercentage(percentage: number): boolean;
|
|
205
249
|
//# sourceMappingURL=validation.d.ts.map
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
package/dist/validation.js
CHANGED
|
@@ -273,3 +273,65 @@ export function hasMinimumSelection(items, minItems = 1) {
|
|
|
273
273
|
export function isSelected(value) {
|
|
274
274
|
return value !== null && value !== undefined && value !== '';
|
|
275
275
|
}
|
|
276
|
+
// ENHANCED VALIDATION UTILITIES (Phase 14)
|
|
277
|
+
/**
|
|
278
|
+
* Validates that percentage values sum to a target value (default 100)
|
|
279
|
+
* @param values - Array of percentage values
|
|
280
|
+
* @param target - Target sum value (default: 100)
|
|
281
|
+
* @param tolerance - Allowed tolerance for floating point differences (default: 0.01)
|
|
282
|
+
* @returns true if sum equals target within tolerance, false otherwise
|
|
283
|
+
* @example
|
|
284
|
+
* validatePercentageSum([25, 25, 50]) // true (sums to 100)
|
|
285
|
+
* validatePercentageSum([33.33, 33.33, 33.34]) // true (within tolerance)
|
|
286
|
+
* validatePercentageSum([50, 30, 15]) // false (sums to 95)
|
|
287
|
+
*/
|
|
288
|
+
export function validatePercentageSum(values, target = 100, tolerance = 0.01) {
|
|
289
|
+
if (!Array.isArray(values) || values.length === 0)
|
|
290
|
+
return false;
|
|
291
|
+
const sum = values.reduce((total, value) => total + (value || 0), 0);
|
|
292
|
+
return Math.abs(sum - target) <= tolerance;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Validates that allocation objects with percentage properties sum to 100%
|
|
296
|
+
* @param allocations - Array of objects with percentage property
|
|
297
|
+
* @param percentageField - Name of the percentage field (default: 'percentage')
|
|
298
|
+
* @param tolerance - Allowed tolerance for floating point differences (default: 0.01)
|
|
299
|
+
* @returns true if sum equals 100 within tolerance, false otherwise
|
|
300
|
+
* @example
|
|
301
|
+
* validateAllocationSum([{percentage: 50}, {percentage: 50}]) // true
|
|
302
|
+
* validateAllocationSum([{percentage: '33.33'}, {percentage: '66.67'}]) // true
|
|
303
|
+
*/
|
|
304
|
+
export function validateAllocationSum(allocations, percentageField = 'percentage', tolerance = 0.01) {
|
|
305
|
+
if (!Array.isArray(allocations) || allocations.length === 0)
|
|
306
|
+
return false;
|
|
307
|
+
const values = allocations.map(allocation => {
|
|
308
|
+
const value = allocation[percentageField];
|
|
309
|
+
return typeof value === 'string' ? parseFloat(value) || 0 : Number(value) || 0;
|
|
310
|
+
});
|
|
311
|
+
return validatePercentageSum(values, 100, tolerance);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Validates that a number is within a specified range (inclusive)
|
|
315
|
+
* @param value - The number to validate
|
|
316
|
+
* @param min - Minimum allowed value
|
|
317
|
+
* @param max - Maximum allowed value
|
|
318
|
+
* @returns true if number is within range, false otherwise
|
|
319
|
+
* @example
|
|
320
|
+
* isInNumberRange(50, 0, 100) // true
|
|
321
|
+
* isInNumberRange(150, 0, 100) // false
|
|
322
|
+
*/
|
|
323
|
+
export function isInNumberRange(value, min, max) {
|
|
324
|
+
return typeof value === 'number' && !isNaN(value) && value >= min && value <= max;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Validates that a percentage is between 0 and 100
|
|
328
|
+
* @param percentage - The percentage to validate
|
|
329
|
+
* @returns true if valid percentage, false otherwise
|
|
330
|
+
* @example
|
|
331
|
+
* isValidPercentage(50) // true
|
|
332
|
+
* isValidPercentage(150) // false
|
|
333
|
+
* isValidPercentage(-10) // false
|
|
334
|
+
*/
|
|
335
|
+
export function isValidPercentage(percentage) {
|
|
336
|
+
return isInNumberRange(percentage, 0, 100);
|
|
337
|
+
}
|