@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 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
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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, } 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,
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, } from './filters';
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"}
@@ -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
+ }
@@ -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
@@ -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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"}
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cranberry-money/shared-utils",
3
- "version": "4.12.0",
3
+ "version": "4.14.0",
4
4
  "description": "Shared utility functions for MyPortfolio platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",