@cranberry-money/shared-services 1.2.0 → 1.3.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.
Files changed (28) hide show
  1. package/dist/services/portfolios/allocations/index.d.ts +7 -0
  2. package/dist/services/portfolios/allocations/index.d.ts.map +1 -0
  3. package/dist/services/portfolios/allocations/index.js +6 -0
  4. package/dist/services/portfolios/allocations/service.d.ts +6 -0
  5. package/dist/services/portfolios/allocations/service.d.ts.map +1 -0
  6. package/dist/services/portfolios/allocations/service.js +19 -0
  7. package/dist/services/portfolios/allocations/types.d.ts +17 -0
  8. package/dist/services/portfolios/allocations/types.d.ts.map +1 -0
  9. package/dist/services/portfolios/allocations/types.js +4 -0
  10. package/dist/services/portfolios/allocations/utils.d.ts +3 -0
  11. package/dist/services/portfolios/allocations/utils.d.ts.map +1 -0
  12. package/dist/services/portfolios/allocations/utils.js +7 -0
  13. package/dist/services/portfolios/holdings/index.d.ts +7 -0
  14. package/dist/services/portfolios/holdings/index.d.ts.map +1 -0
  15. package/dist/services/portfolios/holdings/index.js +6 -0
  16. package/dist/services/portfolios/holdings/service.d.ts +10 -0
  17. package/dist/services/portfolios/holdings/service.d.ts.map +1 -0
  18. package/dist/services/portfolios/holdings/service.js +53 -0
  19. package/dist/services/portfolios/holdings/types.d.ts +42 -0
  20. package/dist/services/portfolios/holdings/types.d.ts.map +1 -0
  21. package/dist/services/portfolios/holdings/types.js +4 -0
  22. package/dist/services/portfolios/holdings/utils.d.ts +8 -0
  23. package/dist/services/portfolios/holdings/utils.d.ts.map +1 -0
  24. package/dist/services/portfolios/holdings/utils.js +82 -0
  25. package/dist/services/portfolios/index.d.ts +2 -0
  26. package/dist/services/portfolios/index.d.ts.map +1 -1
  27. package/dist/services/portfolios/index.js +3 -0
  28. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Portfolio allocations service exports
3
+ */
4
+ export * from './types';
5
+ export * from './service';
6
+ export * from './utils';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/allocations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Portfolio allocations service exports
3
+ */
4
+ export * from './types';
5
+ export * from './service';
6
+ export * from './utils';
@@ -0,0 +1,6 @@
1
+ import type { AssetAllocation, AssetAllocationPayload } from './types';
2
+ export declare const getPortfolioAllocations: (portfolioUuid: string) => Promise<import("axios").AxiosResponse<AssetAllocation[], any>>;
3
+ export declare const createAssetAllocation: (data: AssetAllocationPayload) => Promise<import("axios").AxiosResponse<AssetAllocation, any>>;
4
+ export declare const updateAssetAllocation: (uuid: string, data: Partial<AssetAllocationPayload>) => Promise<import("axios").AxiosResponse<AssetAllocation, any>>;
5
+ export declare const deleteAssetAllocation: (uuid: string) => Promise<import("axios").AxiosResponse<void, any>>;
6
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/allocations/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAKvE,eAAO,MAAM,uBAAuB,GAAI,eAAe,MAAM,mEAK5D,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM,sBAAsB,iEAEjE,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,iEAExF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,sDAEjD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { webApiClient } from '../../../api/apiClient';
2
+ import { API_ENDPOINTS } from '../constants';
3
+ // ASSET ALLOCATIONS API FUNCTIONS
4
+ // Fetch allocations for a specific portfolio
5
+ export const getPortfolioAllocations = (portfolioUuid) => {
6
+ // Always sort by created_at to show allocations in their creation order
7
+ return webApiClient.get(`${API_ENDPOINTS.PORTFOLIOS}${portfolioUuid}/allocations/`, {
8
+ params: { order_by: 'created_at' },
9
+ });
10
+ };
11
+ export const createAssetAllocation = (data) => {
12
+ return webApiClient.post(API_ENDPOINTS.ASSET_ALLOCATIONS, data);
13
+ };
14
+ export const updateAssetAllocation = (uuid, data) => {
15
+ return webApiClient.patch(`${API_ENDPOINTS.ASSET_ALLOCATIONS}${uuid}/`, data);
16
+ };
17
+ export const deleteAssetAllocation = (uuid) => {
18
+ return webApiClient.delete(`${API_ENDPOINTS.ASSET_ALLOCATIONS}${uuid}/`);
19
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Asset Allocations types and interfaces
3
+ */
4
+ export interface AssetAllocation {
5
+ uuid: string;
6
+ portfolio: string;
7
+ instrument: string;
8
+ instrumentName: string;
9
+ instrumentSymbol: string;
10
+ percentage: string;
11
+ }
12
+ export interface AssetAllocationPayload {
13
+ portfolio: string;
14
+ instrument: string;
15
+ percentage: string | number;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/allocations/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Asset Allocations types and interfaces
3
+ */
4
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AssetAllocation } from './types';
2
+ export declare const validateAllocations: (allocations: AssetAllocation[]) => boolean;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/allocations/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C,eAAO,MAAM,mBAAmB,GAAI,aAAa,eAAe,EAAE,KAAG,OAKpE,CAAC"}
@@ -0,0 +1,7 @@
1
+ // ASSET ALLOCATIONS UTILITY FUNCTIONS
2
+ // Utility function to validate if allocation percentages sum to 100%
3
+ export const validateAllocations = (allocations) => {
4
+ const totalPercentage = allocations.reduce((sum, allocation) => sum + parseFloat(allocation.percentage), 0);
5
+ // Allow for small floating point errors (e.g., 99.99 or 100.01)
6
+ return Math.abs(totalPercentage - 100) < 0.01;
7
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Portfolio holdings service exports
3
+ */
4
+ export * from './types';
5
+ export * from './service';
6
+ export * from './utils';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/holdings/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Portfolio holdings service exports
3
+ */
4
+ export * from './types';
5
+ export * from './service';
6
+ export * from './utils';
@@ -0,0 +1,10 @@
1
+ import type { PaginatedResponse } from '../../../api/types';
2
+ import type { AssetHolding, AssetHoldingSnapshot, AssetHoldingFilters, AssetHoldingSnapshotFilters } from './types';
3
+ export type PaginatedAssetHoldings = PaginatedResponse<AssetHolding>;
4
+ export type PaginatedAssetHoldingSnapshots = PaginatedResponse<AssetHoldingSnapshot>;
5
+ export declare const getAssetHoldings: (filters?: AssetHoldingFilters) => Promise<import("axios").AxiosResponse<PaginatedAssetHoldings, any>>;
6
+ export declare const getPortfolioHoldings: (portfolioUuid: string, orderBy?: string) => Promise<import("axios").AxiosResponse<AssetHolding[], any>>;
7
+ export declare const getAssetHoldingByUuid: (uuid: string) => Promise<import("axios").AxiosResponse<AssetHolding, any>>;
8
+ export declare const getAssetHoldingSnapshots: (filters?: AssetHoldingSnapshotFilters) => Promise<import("axios").AxiosResponse<PaginatedAssetHoldingSnapshots, any>>;
9
+ export declare const getAssetHoldingSnapshotById: (id: number) => Promise<import("axios").AxiosResponse<AssetHoldingSnapshot, any>>;
10
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/holdings/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAGpH,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;AACrE,MAAM,MAAM,8BAA8B,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;AAKrF,eAAO,MAAM,gBAAgB,GAAI,UAAU,mBAAmB,wEAW7D,CAAC;AAGF,eAAO,MAAM,oBAAoB,GAAI,eAAe,MAAM,EAAE,UAAU,MAAM,gEAK3E,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,8DAEjD,CAAC;AAKF,eAAO,MAAM,wBAAwB,GAAI,UAAU,2BAA2B,gFAW7E,CAAC;AAGF,eAAO,MAAM,2BAA2B,GAAI,IAAI,MAAM,sEAErD,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { webApiClient } from '../../../api/apiClient';
2
+ import { API_ENDPOINTS } from '../constants';
3
+ // ASSET HOLDINGS API FUNCTIONS
4
+ // Fetch asset holdings with optional filtering
5
+ export const getAssetHoldings = (filters) => {
6
+ const params = {};
7
+ if (filters?.portfolioId)
8
+ params.portfolio_id = filters.portfolioId;
9
+ if (filters?.portfolioUuid)
10
+ params.portfolio_uuid = filters.portfolioUuid;
11
+ if (filters?.instrument)
12
+ params.instrument = filters.instrument;
13
+ if (filters?.minQuantity)
14
+ params.min_quantity = filters.minQuantity.toString();
15
+ if (filters?.maxQuantity)
16
+ params.max_quantity = filters.maxQuantity.toString();
17
+ if (filters?.orderBy)
18
+ params.order_by = filters.orderBy;
19
+ return webApiClient.get(API_ENDPOINTS.ASSET_HOLDINGS, { params });
20
+ };
21
+ // Fetch holdings for a specific portfolio
22
+ export const getPortfolioHoldings = (portfolioUuid, orderBy) => {
23
+ const params = {};
24
+ if (orderBy)
25
+ params.order_by = orderBy;
26
+ return webApiClient.get(`${API_ENDPOINTS.PORTFOLIOS}${portfolioUuid}/holdings/`, { params });
27
+ };
28
+ // Get asset holding by UUID
29
+ export const getAssetHoldingByUuid = (uuid) => {
30
+ return webApiClient.get(`${API_ENDPOINTS.ASSET_HOLDINGS}${uuid}/`);
31
+ };
32
+ // ASSET HOLDING SNAPSHOTS API FUNCTIONS
33
+ // Fetch asset holding snapshots with optional filtering
34
+ export const getAssetHoldingSnapshots = (filters) => {
35
+ const params = {};
36
+ if (filters?.assetHoldingId)
37
+ params.asset_holding_id = filters.assetHoldingId;
38
+ if (filters?.portfolioId)
39
+ params.portfolio_id = filters.portfolioId;
40
+ if (filters?.reason)
41
+ params.reason = filters.reason;
42
+ if (filters?.startDate)
43
+ params.start_date = filters.startDate;
44
+ if (filters?.endDate)
45
+ params.end_date = filters.endDate;
46
+ if (filters?.orderBy)
47
+ params.order_by = filters.orderBy;
48
+ return webApiClient.get(API_ENDPOINTS.ASSET_HOLDING_SNAPSHOTS, { params });
49
+ };
50
+ // Get asset holding snapshot by ID
51
+ export const getAssetHoldingSnapshotById = (id) => {
52
+ return webApiClient.get(`${API_ENDPOINTS.ASSET_HOLDING_SNAPSHOTS}${id}/`);
53
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Asset Holdings types and interfaces
3
+ */
4
+ export interface AssetHolding {
5
+ uuid: string;
6
+ portfolio: string;
7
+ instrument: any;
8
+ instrumentName: string;
9
+ instrumentSymbol: string;
10
+ quantity: number;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+ export interface AssetHoldingSnapshot {
15
+ id: number;
16
+ assetHolding: string;
17
+ portfolioId: number;
18
+ instrumentName: string;
19
+ instrumentSymbol: string;
20
+ quantity: number;
21
+ snapshotReason: 'TRADE' | 'REBALANCE' | 'VALUATION' | 'AUDIT';
22
+ snapshotDate: string;
23
+ createdAt: string;
24
+ updatedAt: string;
25
+ }
26
+ export interface AssetHoldingFilters {
27
+ portfolioId?: string;
28
+ portfolioUuid?: string;
29
+ instrument?: string;
30
+ minQuantity?: number;
31
+ maxQuantity?: number;
32
+ orderBy?: string;
33
+ }
34
+ export interface AssetHoldingSnapshotFilters {
35
+ assetHoldingId?: string;
36
+ portfolioId?: string;
37
+ reason?: 'TRADE' | 'REBALANCE' | 'VALUATION' | 'AUDIT';
38
+ startDate?: string;
39
+ endDate?: string;
40
+ orderBy?: string;
41
+ }
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/holdings/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,GAAG,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,2BAA2B;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Asset Holdings types and interfaces
3
+ */
4
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { AssetHolding } from './types';
2
+ export declare const calculatePortfolioValue: (holdings: AssetHolding[], prices: Record<string, number>) => number;
3
+ export declare const calculateHoldingAllocations: (holdings: AssetHolding[]) => Record<string, number>;
4
+ export declare const groupHoldingsByInstrument: (holdings: AssetHolding[]) => Record<string, AssetHolding[]>;
5
+ export declare const filterHoldingsByMinQuantity: (holdings: AssetHolding[], minQuantity: number) => AssetHolding[];
6
+ export declare const sortHoldings: (holdings: AssetHolding[], sortBy: "quantity" | "symbol" | "name" | "createdAt", direction?: "asc" | "desc") => AssetHolding[];
7
+ export declare const formatQuantity: (quantity: number) => string;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/services/portfolios/holdings/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK5C,eAAO,MAAM,uBAAuB,GAAI,UAAU,YAAY,EAAE,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MAKlG,CAAC;AAGF,eAAO,MAAM,2BAA2B,GAAI,UAAU,YAAY,EAAE,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAW3F,CAAC;AAGF,eAAO,MAAM,yBAAyB,GAAI,UAAU,YAAY,EAAE,KAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAYjG,CAAC;AAGF,eAAO,MAAM,2BAA2B,GAAI,UAAU,YAAY,EAAE,EAAE,aAAa,MAAM,KAAG,YAAY,EAEvG,CAAC;AAGF,eAAO,MAAM,YAAY,GACvB,UAAU,YAAY,EAAE,EACxB,QAAQ,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,EACpD,YAAW,KAAK,GAAG,MAAe,KACjC,YAAY,EAsCd,CAAC;AAGF,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,MAQjD,CAAC"}
@@ -0,0 +1,82 @@
1
+ // ASSET HOLDINGS UTILITY FUNCTIONS
2
+ // Calculate total portfolio value based on holdings and prices
3
+ export const calculatePortfolioValue = (holdings, prices) => {
4
+ return holdings.reduce((total, holding) => {
5
+ const price = prices[holding.instrument.uuid] || 0;
6
+ return total + holding.quantity * price;
7
+ }, 0);
8
+ };
9
+ // Calculate holding allocation percentages within a portfolio
10
+ export const calculateHoldingAllocations = (holdings) => {
11
+ const totalQuantity = holdings.reduce((sum, holding) => sum + holding.quantity, 0);
12
+ if (totalQuantity === 0)
13
+ return {};
14
+ const allocations = {};
15
+ holdings.forEach((holding) => {
16
+ allocations[holding.instrument.uuid] = (holding.quantity / totalQuantity) * 100;
17
+ });
18
+ return allocations;
19
+ };
20
+ // Group holdings by instrument for aggregated view
21
+ export const groupHoldingsByInstrument = (holdings) => {
22
+ return holdings.reduce((groups, holding) => {
23
+ const instrumentUuid = holding.instrument.uuid;
24
+ if (!groups[instrumentUuid]) {
25
+ groups[instrumentUuid] = [];
26
+ }
27
+ groups[instrumentUuid].push(holding);
28
+ return groups;
29
+ }, {});
30
+ };
31
+ // Filter holdings with quantities above a threshold
32
+ export const filterHoldingsByMinQuantity = (holdings, minQuantity) => {
33
+ return holdings.filter((holding) => holding.quantity >= minQuantity);
34
+ };
35
+ // Sort holdings by various criteria
36
+ export const sortHoldings = (holdings, sortBy, direction = 'desc') => {
37
+ return [...holdings].sort((a, b) => {
38
+ let valueA;
39
+ let valueB;
40
+ switch (sortBy) {
41
+ case 'quantity':
42
+ valueA = a.quantity;
43
+ valueB = b.quantity;
44
+ break;
45
+ case 'symbol':
46
+ valueA = a.instrumentSymbol;
47
+ valueB = b.instrumentSymbol;
48
+ break;
49
+ case 'name':
50
+ valueA = a.instrumentName;
51
+ valueB = b.instrumentName;
52
+ break;
53
+ case 'createdAt':
54
+ valueA = a.createdAt;
55
+ valueB = b.createdAt;
56
+ break;
57
+ default:
58
+ return 0;
59
+ }
60
+ if (typeof valueA === 'string' && typeof valueB === 'string') {
61
+ const comparison = valueA.localeCompare(valueB);
62
+ return direction === 'asc' ? comparison : -comparison;
63
+ }
64
+ if (typeof valueA === 'number' && typeof valueB === 'number') {
65
+ const comparison = valueA - valueB;
66
+ return direction === 'asc' ? comparison : -comparison;
67
+ }
68
+ return 0;
69
+ });
70
+ };
71
+ // Format quantity for display with proper units
72
+ export const formatQuantity = (quantity) => {
73
+ if (quantity >= 1000000) {
74
+ return `${(quantity / 1000000).toFixed(1)}M`;
75
+ }
76
+ else if (quantity >= 1000) {
77
+ return `${(quantity / 1000).toFixed(1)}K`;
78
+ }
79
+ else {
80
+ return quantity.toString();
81
+ }
82
+ };
@@ -5,4 +5,6 @@ export * from './constants';
5
5
  export * from './types';
6
6
  export * from './service';
7
7
  export * from './utils';
8
+ export * as Allocations from './allocations';
9
+ export * as Holdings from './holdings';
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/portfolios/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/portfolios/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,WAAW,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC"}
@@ -5,3 +5,6 @@ export * from './constants';
5
5
  export * from './types';
6
6
  export * from './service';
7
7
  export * from './utils';
8
+ // Sub-services
9
+ export * as Allocations from './allocations';
10
+ export * as Holdings from './holdings';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cranberry-money/shared-services",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Shared API services and client for MyPortfolio platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",