@cranberry-money/shared-utils 8.11.0 → 8.13.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
@@ -30,4 +30,6 @@ export { sortSectorsByName, filterSectorsByName, findSectorByName, getSectorName
30
30
  export { generateDocumentFilename, formatDocumentType, formatDocumentStatus, } from './document';
31
31
  export { sortIndustriesByName, filterIndustriesByName, filterIndustriesBySector, findIndustryByName, getIndustryNames, groupIndustriesBySector, groupIndustriesAlphabetically, getIndustriesWithoutSector, getIndustriesWithSector, countIndustriesBySector, isIndustryInSector, type BaseIndustry, } from './industry';
32
32
  export { sortCountriesByName, filterCountriesByName, filterAvailableCountries, findCountryByName, findCountryByCode, getCountryNames, groupCountriesAlphabetically, formatCountryWithDialCode, isCountryAvailable, type BaseCountry as BaseCountryType, } from './country';
33
+ export { calculateTotalAllocation, validateAllocationPercentages, formatRiskLevelDisplay, type BaseAllocation, } from './portfolio-template';
34
+ export { validateInvestmentAmount, formatInvestmentAmount, } from './investment-preference';
33
35
  //# 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,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGnE,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,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAGtB,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,EAEV,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,qBAAqB,EAErB,0BAA0B,EAC1B,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,2BAA2B,EAC3B,6BAA6B,EAC7B,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,aAAa,GACd,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,2BAA2B,EAC3B,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,WAAW,GACZ,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,EACL,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,2BAA2B,EAC3B,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,KAAK,4BAA4B,EACjC,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,yBAAyB,EACzB,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,wBAAwB,EACxB,4BAA4B,EAC5B,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,YAAY,EACZ,wBAAwB,EACxB,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,KAAK,WAAW,IAAI,eAAe,GACpC,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -60,3 +60,7 @@ export { generateDocumentFilename, formatDocumentType, formatDocumentStatus, } f
60
60
  export { sortIndustriesByName, filterIndustriesByName, filterIndustriesBySector, findIndustryByName, getIndustryNames, groupIndustriesBySector, groupIndustriesAlphabetically, getIndustriesWithoutSector, getIndustriesWithSector, countIndustriesBySector, isIndustryInSector, } from './industry';
61
61
  // Country utilities
62
62
  export { sortCountriesByName, filterCountriesByName, filterAvailableCountries, findCountryByName, findCountryByCode, getCountryNames, groupCountriesAlphabetically, formatCountryWithDialCode, isCountryAvailable, } from './country';
63
+ // Portfolio template utilities
64
+ export { calculateTotalAllocation, validateAllocationPercentages, formatRiskLevelDisplay, } from './portfolio-template';
65
+ // Investment preference utilities
66
+ export { validateInvestmentAmount, formatInvestmentAmount, } from './investment-preference';
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Validate investment amount using shared validation utilities
3
+ *
4
+ * @param amount - Investment amount to validate
5
+ * @returns True if amount is valid for investment
6
+ *
7
+ * @example
8
+ * validateInvestmentAmount(1000); // returns true
9
+ * validateInvestmentAmount(-100); // returns false
10
+ * validateInvestmentAmount(0); // returns false
11
+ */
12
+ export declare const validateInvestmentAmount: (amount: number) => boolean;
13
+ /**
14
+ * Format investment amount for display with USD currency
15
+ *
16
+ * @param amount - Amount string to format
17
+ * @returns Formatted currency string with USD code
18
+ *
19
+ * @example
20
+ * formatInvestmentAmount('1000'); // returns '$1,000.00 USD'
21
+ * formatInvestmentAmount('invalid'); // returns '$0.00 USD'
22
+ * formatInvestmentAmount('1500.50'); // returns '$1,500.50 USD'
23
+ */
24
+ export declare const formatInvestmentAmount: (amount: string) => string;
25
+ //# sourceMappingURL=investment-preference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"investment-preference.d.ts","sourceRoot":"","sources":["../src/investment-preference.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,KAAG,OAEzD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,KAAG,MAIvD,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { isValidInvestmentAmount } from './validation';
2
+ import { formatCurrencyWithCode } from './currency';
3
+ /**
4
+ * Validate investment amount using shared validation utilities
5
+ *
6
+ * @param amount - Investment amount to validate
7
+ * @returns True if amount is valid for investment
8
+ *
9
+ * @example
10
+ * validateInvestmentAmount(1000); // returns true
11
+ * validateInvestmentAmount(-100); // returns false
12
+ * validateInvestmentAmount(0); // returns false
13
+ */
14
+ export const validateInvestmentAmount = (amount) => {
15
+ return isValidInvestmentAmount(amount);
16
+ };
17
+ /**
18
+ * Format investment amount for display with USD currency
19
+ *
20
+ * @param amount - Amount string to format
21
+ * @returns Formatted currency string with USD code
22
+ *
23
+ * @example
24
+ * formatInvestmentAmount('1000'); // returns '$1,000.00 USD'
25
+ * formatInvestmentAmount('invalid'); // returns '$0.00 USD'
26
+ * formatInvestmentAmount('1500.50'); // returns '$1,500.50 USD'
27
+ */
28
+ export const formatInvestmentAmount = (amount) => {
29
+ const num = parseFloat(amount);
30
+ if (isNaN(num))
31
+ return formatCurrencyWithCode(0, 'USD', 'en-US', 2, 2);
32
+ return formatCurrencyWithCode(num, 'USD', 'en-US', 2, 2);
33
+ };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Base interface for allocation objects
3
+ */
4
+ export interface BaseAllocation {
5
+ readonly percentage: string;
6
+ }
7
+ /**
8
+ * Calculate total allocation from an array of allocations
9
+ *
10
+ * @param allocations - Array of allocation objects with percentage strings
11
+ * @returns Total allocation as a number
12
+ *
13
+ * @example
14
+ * const total = calculateTotalAllocation([
15
+ * { percentage: '50.5' },
16
+ * { percentage: '30.0' },
17
+ * { percentage: '19.5' }
18
+ * ]);
19
+ * // Returns 100.0
20
+ */
21
+ export declare const calculateTotalAllocation: <T extends BaseAllocation>(allocations: readonly T[]) => number;
22
+ /**
23
+ * Validate that allocation percentages sum to approximately 100%
24
+ *
25
+ * @param allocations - Array of allocation objects with percentage strings
26
+ * @param tolerance - Tolerance for percentage validation (default: 0.01)
27
+ * @returns True if allocations sum to approximately 100%
28
+ *
29
+ * @example
30
+ * const isValid = validateAllocationPercentages([
31
+ * { percentage: '50.0' },
32
+ * { percentage: '30.0' },
33
+ * { percentage: '20.0' }
34
+ * ]);
35
+ * // Returns true
36
+ *
37
+ * @example
38
+ * const isValid = validateAllocationPercentages([
39
+ * { percentage: '50.0' },
40
+ * { percentage: '30.0' },
41
+ * { percentage: '15.0' }
42
+ * ]);
43
+ * // Returns false (sums to 95%)
44
+ */
45
+ export declare const validateAllocationPercentages: <T extends BaseAllocation>(allocations: readonly T[], tolerance?: number) => boolean;
46
+ /**
47
+ * Format risk level for display (re-export from formatting utilities)
48
+ *
49
+ * @param riskLevel - Risk level string to format
50
+ * @returns Formatted risk level string
51
+ *
52
+ * @example
53
+ * formatRiskLevelDisplay('HIGH'); // returns 'High'
54
+ * formatRiskLevelDisplay('moderate'); // returns 'Moderate'
55
+ */
56
+ export declare const formatRiskLevelDisplay: (riskLevel: string) => string;
57
+ //# sourceMappingURL=portfolio-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"portfolio-template.d.ts","sourceRoot":"","sources":["../src/portfolio-template.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,cAAc,EAC/D,aAAa,SAAS,CAAC,EAAE,KACxB,MAIF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,6BAA6B,GAAI,CAAC,SAAS,cAAc,EACpE,aAAa,SAAS,CAAC,EAAE,EACzB,YAAW,MAAa,KACvB,OAGF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GAAI,WAAW,MAAM,KAAG,MAE1D,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { formatRiskLevel } from './formatting';
2
+ /**
3
+ * Calculate total allocation from an array of allocations
4
+ *
5
+ * @param allocations - Array of allocation objects with percentage strings
6
+ * @returns Total allocation as a number
7
+ *
8
+ * @example
9
+ * const total = calculateTotalAllocation([
10
+ * { percentage: '50.5' },
11
+ * { percentage: '30.0' },
12
+ * { percentage: '19.5' }
13
+ * ]);
14
+ * // Returns 100.0
15
+ */
16
+ export const calculateTotalAllocation = (allocations) => {
17
+ return allocations.reduce((total, allocation) => {
18
+ return total + parseFloat(allocation.percentage || '0');
19
+ }, 0);
20
+ };
21
+ /**
22
+ * Validate that allocation percentages sum to approximately 100%
23
+ *
24
+ * @param allocations - Array of allocation objects with percentage strings
25
+ * @param tolerance - Tolerance for percentage validation (default: 0.01)
26
+ * @returns True if allocations sum to approximately 100%
27
+ *
28
+ * @example
29
+ * const isValid = validateAllocationPercentages([
30
+ * { percentage: '50.0' },
31
+ * { percentage: '30.0' },
32
+ * { percentage: '20.0' }
33
+ * ]);
34
+ * // Returns true
35
+ *
36
+ * @example
37
+ * const isValid = validateAllocationPercentages([
38
+ * { percentage: '50.0' },
39
+ * { percentage: '30.0' },
40
+ * { percentage: '15.0' }
41
+ * ]);
42
+ * // Returns false (sums to 95%)
43
+ */
44
+ export const validateAllocationPercentages = (allocations, tolerance = 0.01) => {
45
+ const total = calculateTotalAllocation(allocations);
46
+ return Math.abs(total - 100) <= tolerance;
47
+ };
48
+ /**
49
+ * Format risk level for display (re-export from formatting utilities)
50
+ *
51
+ * @param riskLevel - Risk level string to format
52
+ * @returns Formatted risk level string
53
+ *
54
+ * @example
55
+ * formatRiskLevelDisplay('HIGH'); // returns 'High'
56
+ * formatRiskLevelDisplay('moderate'); // returns 'Moderate'
57
+ */
58
+ export const formatRiskLevelDisplay = (riskLevel) => {
59
+ return formatRiskLevel(riskLevel);
60
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cranberry-money/shared-utils",
3
- "version": "8.11.0",
3
+ "version": "8.13.0",
4
4
  "description": "Shared utility functions for MyPortfolio platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",