@cranberry-money/shared-services 4.0.0 → 4.1.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/package.json +4 -3
- package/dist/api/functional-client.d.ts +0 -66
- package/dist/api/functional-client.d.ts.map +0 -1
- package/dist/api/functional-client.js +0 -165
- package/dist/auth/functional/auth-operations.d.ts +0 -116
- package/dist/auth/functional/auth-operations.d.ts.map +0 -1
- package/dist/auth/functional/auth-operations.js +0 -246
- package/dist/auth/functional/auth-state.d.ts +0 -38
- package/dist/auth/functional/auth-state.d.ts.map +0 -1
- package/dist/auth/functional/auth-state.js +0 -87
- package/dist/auth/functional/token-storage.d.ts +0 -44
- package/dist/auth/functional/token-storage.d.ts.map +0 -1
- package/dist/auth/functional/token-storage.js +0 -178
- package/dist/auth/react/AuthProvider.d.ts +0 -92
- package/dist/auth/react/AuthProvider.d.ts.map +0 -1
- package/dist/auth/react/AuthProvider.js +0 -207
- package/dist/integration/blueberry-integration.d.ts +0 -21
- package/dist/integration/blueberry-integration.d.ts.map +0 -1
- package/dist/integration/blueberry-integration.js +0 -109
- package/dist/integration/index.d.ts +0 -8
- package/dist/integration/index.d.ts.map +0 -1
- package/dist/integration/index.js +0 -18
- package/dist/services/accounts.d.ts +0 -220
- package/dist/services/accounts.d.ts.map +0 -1
- package/dist/services/accounts.js +0 -175
- package/dist/services/banks.d.ts +0 -123
- package/dist/services/banks.d.ts.map +0 -1
- package/dist/services/banks.js +0 -151
- package/dist/services/cash-accounts.d.ts +0 -112
- package/dist/services/cash-accounts.d.ts.map +0 -1
- package/dist/services/cash-accounts.js +0 -222
- package/dist/services/documents.d.ts +0 -143
- package/dist/services/documents.d.ts.map +0 -1
- package/dist/services/documents.js +0 -253
- package/dist/services/factories/account-factory.d.ts +0 -16
- package/dist/services/factories/account-factory.d.ts.map +0 -1
- package/dist/services/factories/account-factory.js +0 -79
- package/dist/services/factories/auth-factory.d.ts +0 -23
- package/dist/services/factories/auth-factory.d.ts.map +0 -1
- package/dist/services/factories/auth-factory.js +0 -75
- package/dist/services/factories/bank-factory.d.ts +0 -16
- package/dist/services/factories/bank-factory.d.ts.map +0 -1
- package/dist/services/factories/bank-factory.js +0 -72
- package/dist/services/factories/cash-account-factory.d.ts +0 -16
- package/dist/services/factories/cash-account-factory.d.ts.map +0 -1
- package/dist/services/factories/cash-account-factory.js +0 -74
- package/dist/services/factories/document-factory.d.ts +0 -16
- package/dist/services/factories/document-factory.d.ts.map +0 -1
- package/dist/services/factories/document-factory.js +0 -85
- package/dist/services/factories/index.d.ts +0 -21
- package/dist/services/factories/index.d.ts.map +0 -1
- package/dist/services/factories/index.js +0 -40
- package/dist/services/factories/instrument-factory.d.ts +0 -16
- package/dist/services/factories/instrument-factory.d.ts.map +0 -1
- package/dist/services/factories/instrument-factory.js +0 -68
- package/dist/services/factories/master-factory.d.ts +0 -74
- package/dist/services/factories/master-factory.d.ts.map +0 -1
- package/dist/services/factories/master-factory.js +0 -183
- package/dist/services/factories/portfolio-factory.d.ts +0 -16
- package/dist/services/factories/portfolio-factory.d.ts.map +0 -1
- package/dist/services/factories/portfolio-factory.js +0 -74
- package/dist/services/factories/portfolio-template-factory.d.ts +0 -16
- package/dist/services/factories/portfolio-template-factory.d.ts.map +0 -1
- package/dist/services/factories/portfolio-template-factory.js +0 -76
- package/dist/services/factories/reference-data-factory.d.ts +0 -16
- package/dist/services/factories/reference-data-factory.d.ts.map +0 -1
- package/dist/services/factories/reference-data-factory.js +0 -86
- package/dist/services/factories/tax-residency-factory.d.ts +0 -16
- package/dist/services/factories/tax-residency-factory.d.ts.map +0 -1
- package/dist/services/factories/tax-residency-factory.js +0 -73
- package/dist/services/factories/trade-factory.d.ts +0 -16
- package/dist/services/factories/trade-factory.d.ts.map +0 -1
- package/dist/services/factories/trade-factory.js +0 -79
- package/dist/services/factories/types.d.ts +0 -250
- package/dist/services/factories/types.d.ts.map +0 -1
- package/dist/services/factories/types.js +0 -32
- package/dist/services/factories/withdrawal-factory.d.ts +0 -16
- package/dist/services/factories/withdrawal-factory.d.ts.map +0 -1
- package/dist/services/factories/withdrawal-factory.js +0 -78
- package/dist/services/instruments.d.ts +0 -138
- package/dist/services/instruments.d.ts.map +0 -1
- package/dist/services/instruments.js +0 -178
- package/dist/services/portfolio-templates.d.ts +0 -142
- package/dist/services/portfolio-templates.d.ts.map +0 -1
- package/dist/services/portfolio-templates.js +0 -201
- package/dist/services/portfolios.d.ts +0 -157
- package/dist/services/portfolios.d.ts.map +0 -1
- package/dist/services/portfolios.js +0 -144
- package/dist/services/reference-data.d.ts +0 -185
- package/dist/services/reference-data.d.ts.map +0 -1
- package/dist/services/reference-data.js +0 -245
- package/dist/services/tax-residencies.d.ts +0 -83
- package/dist/services/tax-residencies.d.ts.map +0 -1
- package/dist/services/tax-residencies.js +0 -179
- package/dist/services/trades.d.ts +0 -190
- package/dist/services/trades.d.ts.map +0 -1
- package/dist/services/trades.js +0 -207
- package/dist/services/withdrawals.d.ts +0 -236
- package/dist/services/withdrawals.d.ts.map +0 -1
- package/dist/services/withdrawals.js +0 -345
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Pure Authentication State Management
|
|
4
|
-
*
|
|
5
|
-
* Immutable state structures and pure functions for managing authentication state.
|
|
6
|
-
* All state transitions are explicit and predictable.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.requiresSignupCompletion = exports.requiresVerification = exports.getDisplayName = exports.hasValidTokens = exports.isValidAuthState = exports.clearError = exports.updateTokens = exports.createErrorState = exports.createUnauthenticatedState = exports.createAuthenticatedState = exports.createLoadingAuthState = exports.createInitialAuthState = void 0;
|
|
10
|
-
// State factory functions - all pure functions that return new state
|
|
11
|
-
const createInitialAuthState = () => ({
|
|
12
|
-
isAuthenticated: false,
|
|
13
|
-
isLoading: false,
|
|
14
|
-
user: null,
|
|
15
|
-
tokens: null,
|
|
16
|
-
error: null,
|
|
17
|
-
});
|
|
18
|
-
exports.createInitialAuthState = createInitialAuthState;
|
|
19
|
-
const createLoadingAuthState = (currentState) => ({
|
|
20
|
-
...currentState,
|
|
21
|
-
isLoading: true,
|
|
22
|
-
error: null,
|
|
23
|
-
});
|
|
24
|
-
exports.createLoadingAuthState = createLoadingAuthState;
|
|
25
|
-
const createAuthenticatedState = (user, tokens) => ({
|
|
26
|
-
isAuthenticated: true,
|
|
27
|
-
isLoading: false,
|
|
28
|
-
user,
|
|
29
|
-
tokens,
|
|
30
|
-
error: null,
|
|
31
|
-
});
|
|
32
|
-
exports.createAuthenticatedState = createAuthenticatedState;
|
|
33
|
-
const createUnauthenticatedState = () => ({
|
|
34
|
-
isAuthenticated: false,
|
|
35
|
-
isLoading: false,
|
|
36
|
-
user: null,
|
|
37
|
-
tokens: null,
|
|
38
|
-
error: null,
|
|
39
|
-
});
|
|
40
|
-
exports.createUnauthenticatedState = createUnauthenticatedState;
|
|
41
|
-
const createErrorState = (currentState, error) => ({
|
|
42
|
-
...currentState,
|
|
43
|
-
isLoading: false,
|
|
44
|
-
error,
|
|
45
|
-
});
|
|
46
|
-
exports.createErrorState = createErrorState;
|
|
47
|
-
const updateTokens = (currentState, tokens) => ({
|
|
48
|
-
...currentState,
|
|
49
|
-
tokens,
|
|
50
|
-
});
|
|
51
|
-
exports.updateTokens = updateTokens;
|
|
52
|
-
const clearError = (currentState) => ({
|
|
53
|
-
...currentState,
|
|
54
|
-
error: null,
|
|
55
|
-
});
|
|
56
|
-
exports.clearError = clearError;
|
|
57
|
-
// State validation functions
|
|
58
|
-
const isValidAuthState = (state) => {
|
|
59
|
-
// If authenticated, must have user and tokens
|
|
60
|
-
if (state.isAuthenticated) {
|
|
61
|
-
return state.user !== null && state.tokens !== null;
|
|
62
|
-
}
|
|
63
|
-
// If not authenticated, should not have user or tokens
|
|
64
|
-
return state.user === null && state.tokens === null;
|
|
65
|
-
};
|
|
66
|
-
exports.isValidAuthState = isValidAuthState;
|
|
67
|
-
const hasValidTokens = (state) => {
|
|
68
|
-
return state.tokens !== null &&
|
|
69
|
-
state.tokens.access.length > 0 &&
|
|
70
|
-
state.tokens.refresh.length > 0;
|
|
71
|
-
};
|
|
72
|
-
exports.hasValidTokens = hasValidTokens;
|
|
73
|
-
// Utility functions for working with auth state
|
|
74
|
-
const getDisplayName = (user) => {
|
|
75
|
-
if (!user)
|
|
76
|
-
return '';
|
|
77
|
-
return `${user.firstName} ${user.lastName}`.trim() || user.email;
|
|
78
|
-
};
|
|
79
|
-
exports.getDisplayName = getDisplayName;
|
|
80
|
-
const requiresVerification = (user) => {
|
|
81
|
-
return user !== null && !user.isVerified;
|
|
82
|
-
};
|
|
83
|
-
exports.requiresVerification = requiresVerification;
|
|
84
|
-
const requiresSignupCompletion = (user) => {
|
|
85
|
-
return user !== null && !user.isSignupCompleted;
|
|
86
|
-
};
|
|
87
|
-
exports.requiresSignupCompletion = requiresSignupCompletion;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token Storage Implementations
|
|
3
|
-
*
|
|
4
|
-
* Platform-specific token storage implementations that follow the simple TokenStorage interface.
|
|
5
|
-
* Pure functions with explicit error handling.
|
|
6
|
-
*/
|
|
7
|
-
import type { TokenStorage } from './auth-operations';
|
|
8
|
-
export interface SecureStoreInterface {
|
|
9
|
-
setItemAsync(key: string, value: string): Promise<void>;
|
|
10
|
-
getItemAsync(key: string): Promise<string | null>;
|
|
11
|
-
deleteItemAsync(key: string): Promise<void>;
|
|
12
|
-
isAvailableAsync?(): Promise<boolean>;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Create web token storage using localStorage
|
|
16
|
-
*
|
|
17
|
-
* @returns TokenStorage implementation for web browsers
|
|
18
|
-
*/
|
|
19
|
-
export declare const createWebTokenStorage: () => TokenStorage;
|
|
20
|
-
/**
|
|
21
|
-
* Create mobile token storage using secure storage
|
|
22
|
-
*
|
|
23
|
-
* @param secureStore - Platform-specific secure storage implementation
|
|
24
|
-
* @returns TokenStorage implementation for mobile apps
|
|
25
|
-
*/
|
|
26
|
-
export declare const createMobileTokenStorage: (secureStore: SecureStoreInterface) => TokenStorage;
|
|
27
|
-
/**
|
|
28
|
-
* Create in-memory token storage (for testing)
|
|
29
|
-
*
|
|
30
|
-
* @returns TokenStorage implementation that stores tokens in memory
|
|
31
|
-
*/
|
|
32
|
-
export declare const createMemoryTokenStorage: () => TokenStorage;
|
|
33
|
-
/**
|
|
34
|
-
* Utility function to check if secure storage is available (for mobile)
|
|
35
|
-
*/
|
|
36
|
-
export declare const isSecureStorageAvailable: (secureStore: SecureStoreInterface) => Promise<boolean>;
|
|
37
|
-
/**
|
|
38
|
-
* Migrate tokens from old storage format (if needed)
|
|
39
|
-
*
|
|
40
|
-
* This function can be used to migrate from the old AuthManager token storage
|
|
41
|
-
* to the new simplified format.
|
|
42
|
-
*/
|
|
43
|
-
export declare const migrateTokensFromLegacyStorage: (newStorage: TokenStorage) => Promise<boolean>;
|
|
44
|
-
//# sourceMappingURL=token-storage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-storage.d.ts","sourceRoot":"","sources":["../../../src/auth/functional/token-storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjE,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,gBAAgB,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACvC;AAKD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAO,YAwCvC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,aAAa,oBAAoB,KAAG,YA2C3E,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,QAAO,YAgB3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAU,aAAa,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAkBjG,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GACzC,YAAY,YAAY,KACvB,OAAO,CAAC,OAAO,CA2BjB,CAAC"}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Token Storage Implementations
|
|
4
|
-
*
|
|
5
|
-
* Platform-specific token storage implementations that follow the simple TokenStorage interface.
|
|
6
|
-
* Pure functions with explicit error handling.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.migrateTokensFromLegacyStorage = exports.isSecureStorageAvailable = exports.createMemoryTokenStorage = exports.createMobileTokenStorage = exports.createWebTokenStorage = void 0;
|
|
10
|
-
// Storage keys
|
|
11
|
-
const TOKENS_STORAGE_KEY = 'auth_tokens';
|
|
12
|
-
/**
|
|
13
|
-
* Create web token storage using localStorage
|
|
14
|
-
*
|
|
15
|
-
* @returns TokenStorage implementation for web browsers
|
|
16
|
-
*/
|
|
17
|
-
const createWebTokenStorage = () => ({
|
|
18
|
-
async storeTokens(tokens) {
|
|
19
|
-
try {
|
|
20
|
-
const tokenData = JSON.stringify(tokens);
|
|
21
|
-
localStorage.setItem(TOKENS_STORAGE_KEY, tokenData);
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
throw new Error(`Failed to store tokens: ${error}`);
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
async retrieveTokens() {
|
|
28
|
-
try {
|
|
29
|
-
const stored = localStorage.getItem(TOKENS_STORAGE_KEY);
|
|
30
|
-
if (!stored) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
const tokens = JSON.parse(stored);
|
|
34
|
-
// Validate token structure
|
|
35
|
-
if (!tokens.access || !tokens.refresh) {
|
|
36
|
-
throw new Error('Invalid token structure');
|
|
37
|
-
}
|
|
38
|
-
return tokens;
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
// If parsing fails, clear corrupted data
|
|
42
|
-
localStorage.removeItem(TOKENS_STORAGE_KEY);
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
async clearTokens() {
|
|
47
|
-
try {
|
|
48
|
-
localStorage.removeItem(TOKENS_STORAGE_KEY);
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
// localStorage.removeItem doesn't typically throw, but handle just in case
|
|
52
|
-
console.warn('Failed to clear tokens from localStorage:', error);
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
exports.createWebTokenStorage = createWebTokenStorage;
|
|
57
|
-
/**
|
|
58
|
-
* Create mobile token storage using secure storage
|
|
59
|
-
*
|
|
60
|
-
* @param secureStore - Platform-specific secure storage implementation
|
|
61
|
-
* @returns TokenStorage implementation for mobile apps
|
|
62
|
-
*/
|
|
63
|
-
const createMobileTokenStorage = (secureStore) => ({
|
|
64
|
-
async storeTokens(tokens) {
|
|
65
|
-
try {
|
|
66
|
-
const tokenData = JSON.stringify(tokens);
|
|
67
|
-
await secureStore.setItemAsync(TOKENS_STORAGE_KEY, tokenData);
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
throw new Error(`Failed to store tokens in secure storage: ${error}`);
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
async retrieveTokens() {
|
|
74
|
-
try {
|
|
75
|
-
const stored = await secureStore.getItemAsync(TOKENS_STORAGE_KEY);
|
|
76
|
-
if (!stored) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
const tokens = JSON.parse(stored);
|
|
80
|
-
// Validate token structure
|
|
81
|
-
if (!tokens.access || !tokens.refresh) {
|
|
82
|
-
throw new Error('Invalid token structure');
|
|
83
|
-
}
|
|
84
|
-
return tokens;
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
// If parsing fails, clear corrupted data
|
|
88
|
-
try {
|
|
89
|
-
await secureStore.deleteItemAsync(TOKENS_STORAGE_KEY);
|
|
90
|
-
}
|
|
91
|
-
catch (clearError) {
|
|
92
|
-
console.warn('Failed to clear corrupted tokens:', clearError);
|
|
93
|
-
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
async clearTokens() {
|
|
98
|
-
try {
|
|
99
|
-
await secureStore.deleteItemAsync(TOKENS_STORAGE_KEY);
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
console.warn('Failed to clear tokens from secure storage:', error);
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
exports.createMobileTokenStorage = createMobileTokenStorage;
|
|
107
|
-
/**
|
|
108
|
-
* Create in-memory token storage (for testing)
|
|
109
|
-
*
|
|
110
|
-
* @returns TokenStorage implementation that stores tokens in memory
|
|
111
|
-
*/
|
|
112
|
-
const createMemoryTokenStorage = () => {
|
|
113
|
-
let storedTokens = null;
|
|
114
|
-
return {
|
|
115
|
-
async storeTokens(tokens) {
|
|
116
|
-
storedTokens = { ...tokens };
|
|
117
|
-
},
|
|
118
|
-
async retrieveTokens() {
|
|
119
|
-
return storedTokens ? { ...storedTokens } : null;
|
|
120
|
-
},
|
|
121
|
-
async clearTokens() {
|
|
122
|
-
storedTokens = null;
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
};
|
|
126
|
-
exports.createMemoryTokenStorage = createMemoryTokenStorage;
|
|
127
|
-
/**
|
|
128
|
-
* Utility function to check if secure storage is available (for mobile)
|
|
129
|
-
*/
|
|
130
|
-
const isSecureStorageAvailable = async (secureStore) => {
|
|
131
|
-
try {
|
|
132
|
-
if (secureStore.isAvailableAsync) {
|
|
133
|
-
return await secureStore.isAvailableAsync();
|
|
134
|
-
}
|
|
135
|
-
// Test availability by trying to set/get a test value
|
|
136
|
-
const testKey = '_secure_storage_test';
|
|
137
|
-
const testValue = 'test';
|
|
138
|
-
await secureStore.setItemAsync(testKey, testValue);
|
|
139
|
-
const retrieved = await secureStore.getItemAsync(testKey);
|
|
140
|
-
await secureStore.deleteItemAsync(testKey);
|
|
141
|
-
return retrieved === testValue;
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
exports.isSecureStorageAvailable = isSecureStorageAvailable;
|
|
148
|
-
/**
|
|
149
|
-
* Migrate tokens from old storage format (if needed)
|
|
150
|
-
*
|
|
151
|
-
* This function can be used to migrate from the old AuthManager token storage
|
|
152
|
-
* to the new simplified format.
|
|
153
|
-
*/
|
|
154
|
-
const migrateTokensFromLegacyStorage = async (newStorage) => {
|
|
155
|
-
try {
|
|
156
|
-
// Try to find tokens in old locations
|
|
157
|
-
const legacyAccessToken = localStorage.getItem('access_token');
|
|
158
|
-
const legacyRefreshToken = localStorage.getItem('refresh_token');
|
|
159
|
-
if (legacyAccessToken && legacyRefreshToken) {
|
|
160
|
-
const tokens = {
|
|
161
|
-
access: legacyAccessToken,
|
|
162
|
-
refresh: legacyRefreshToken,
|
|
163
|
-
};
|
|
164
|
-
// Store in new format
|
|
165
|
-
await newStorage.storeTokens(tokens);
|
|
166
|
-
// Clean up old storage
|
|
167
|
-
localStorage.removeItem('access_token');
|
|
168
|
-
localStorage.removeItem('refresh_token');
|
|
169
|
-
return true;
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
console.warn('Failed to migrate legacy tokens:', error);
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
exports.migrateTokensFromLegacyStorage = migrateTokensFromLegacyStorage;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* React Authentication Provider
|
|
3
|
-
*
|
|
4
|
-
* Pure functional authentication with React state management.
|
|
5
|
-
* Uses the pure auth functions with React context for state management.
|
|
6
|
-
*/
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import type { AuthState } from '../functional/auth-state';
|
|
9
|
-
import type { AuthDependencies, SigninPayload, SignupPayload } from '../functional/auth-operations';
|
|
10
|
-
interface AuthContextValue {
|
|
11
|
-
state: AuthState;
|
|
12
|
-
signin: (credentials: SigninPayload) => Promise<void>;
|
|
13
|
-
signout: () => Promise<void>;
|
|
14
|
-
signup: (userData: SignupPayload) => Promise<{
|
|
15
|
-
success: boolean;
|
|
16
|
-
message?: string;
|
|
17
|
-
}>;
|
|
18
|
-
refreshTokens: () => Promise<void>;
|
|
19
|
-
verifyEmail: (token: string) => Promise<{
|
|
20
|
-
success: boolean;
|
|
21
|
-
message?: string;
|
|
22
|
-
}>;
|
|
23
|
-
resendVerificationCode: () => Promise<{
|
|
24
|
-
success: boolean;
|
|
25
|
-
message?: string;
|
|
26
|
-
}>;
|
|
27
|
-
clearError: () => void;
|
|
28
|
-
validateSigninCredentials: (credentials: SigninPayload) => string[];
|
|
29
|
-
validateSignupData: (userData: SignupPayload) => string[];
|
|
30
|
-
}
|
|
31
|
-
interface AuthProviderProps {
|
|
32
|
-
children: React.ReactNode;
|
|
33
|
-
dependencies: AuthDependencies;
|
|
34
|
-
autoInitialize?: boolean;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Authentication Provider Component
|
|
38
|
-
*
|
|
39
|
-
* Manages authentication state using pure functions and React state.
|
|
40
|
-
* Provides a clean, predictable interface for authentication operations.
|
|
41
|
-
*/
|
|
42
|
-
export declare const AuthProvider: React.FC<AuthProviderProps>;
|
|
43
|
-
/**
|
|
44
|
-
* Hook to use authentication context
|
|
45
|
-
*
|
|
46
|
-
* @returns Authentication context value
|
|
47
|
-
* @throws Error if used outside AuthProvider
|
|
48
|
-
*/
|
|
49
|
-
export declare const useAuth: () => AuthContextValue;
|
|
50
|
-
/**
|
|
51
|
-
* Hook to get authentication state only (for components that only need to read state)
|
|
52
|
-
*/
|
|
53
|
-
export declare const useAuthState: () => AuthState;
|
|
54
|
-
/**
|
|
55
|
-
* Hook for authentication actions only (for components that only need actions)
|
|
56
|
-
*/
|
|
57
|
-
export declare const useAuthActions: () => {
|
|
58
|
-
signin: (credentials: SigninPayload) => Promise<void>;
|
|
59
|
-
signout: () => Promise<void>;
|
|
60
|
-
signup: (userData: SignupPayload) => Promise<{
|
|
61
|
-
success: boolean;
|
|
62
|
-
message?: string;
|
|
63
|
-
}>;
|
|
64
|
-
refreshTokens: () => Promise<void>;
|
|
65
|
-
verifyEmail: (token: string) => Promise<{
|
|
66
|
-
success: boolean;
|
|
67
|
-
message?: string;
|
|
68
|
-
}>;
|
|
69
|
-
resendVerificationCode: () => Promise<{
|
|
70
|
-
success: boolean;
|
|
71
|
-
message?: string;
|
|
72
|
-
}>;
|
|
73
|
-
clearError: () => void;
|
|
74
|
-
validateSigninCredentials: (credentials: SigninPayload) => string[];
|
|
75
|
-
validateSignupData: (userData: SignupPayload) => string[];
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Higher-order component for components that require authentication
|
|
79
|
-
*/
|
|
80
|
-
export declare const withAuth: <P extends object>(Component: React.ComponentType<P>) => React.ComponentType<P>;
|
|
81
|
-
/**
|
|
82
|
-
* Component for conditional rendering based on authentication state
|
|
83
|
-
*/
|
|
84
|
-
interface AuthGuardProps {
|
|
85
|
-
children: React.ReactNode;
|
|
86
|
-
fallback?: React.ReactNode;
|
|
87
|
-
requireAuth?: boolean;
|
|
88
|
-
requireVerification?: boolean;
|
|
89
|
-
}
|
|
90
|
-
export declare const AuthGuard: React.FC<AuthGuardProps>;
|
|
91
|
-
export {};
|
|
92
|
-
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../src/auth/react/AuthProvider.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAsE,MAAM,OAAO,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAuBpG,UAAU,gBAAgB;IAExB,KAAK,EAAE,SAAS,CAAC;IAGjB,MAAM,EAAE,CAAC,WAAW,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,sBAAsB,EAAE,MAAM,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAG9E,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,yBAAyB,EAAE,CAAC,WAAW,EAAE,aAAa,KAAK,MAAM,EAAE,CAAC;IACpE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,MAAM,EAAE,CAAC;CAC3D;AAGD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAKD;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwIpD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,QAAO,gBAQ1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,SAG/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc;0BAlMH,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC;mBACtC,OAAO,CAAC,IAAI,CAAC;uBACT,aAAa,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;yBAC/D,OAAO,CAAC,IAAI,CAAC;yBACb,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;kCACjD,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;sBAG3D,IAAI;6CACmB,aAAa,KAAK,MAAM,EAAE;mCACpC,aAAa,KAAK,MAAM,EAAE;CAgN1D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,MAAM,EACvC,WAAW,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAChC,KAAK,CAAC,aAAa,CAAC,CAAC,CAcvB,CAAC;AAEF;;GAEG;AACH,UAAU,cAAc;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAiB9C,CAAC"}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AuthGuard = exports.withAuth = exports.useAuthActions = exports.useAuthState = exports.useAuth = exports.AuthProvider = void 0;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
/**
|
|
6
|
-
* React Authentication Provider
|
|
7
|
-
*
|
|
8
|
-
* Pure functional authentication with React state management.
|
|
9
|
-
* Uses the pure auth functions with React context for state management.
|
|
10
|
-
*/
|
|
11
|
-
const react_1 = require("react");
|
|
12
|
-
const auth_state_1 = require("../functional/auth-state");
|
|
13
|
-
const auth_operations_1 = require("../functional/auth-operations");
|
|
14
|
-
// Create context with null default (will throw if used outside provider)
|
|
15
|
-
const AuthContext = (0, react_1.createContext)(null);
|
|
16
|
-
/**
|
|
17
|
-
* Authentication Provider Component
|
|
18
|
-
*
|
|
19
|
-
* Manages authentication state using pure functions and React state.
|
|
20
|
-
* Provides a clean, predictable interface for authentication operations.
|
|
21
|
-
*/
|
|
22
|
-
const AuthProvider = ({ children, dependencies, autoInitialize = true, }) => {
|
|
23
|
-
const [state, setState] = (0, react_1.useState)(auth_state_1.createInitialAuthState);
|
|
24
|
-
// Initialize authentication state from storage
|
|
25
|
-
(0, react_1.useEffect)(() => {
|
|
26
|
-
if (!autoInitialize)
|
|
27
|
-
return;
|
|
28
|
-
const initialize = async () => {
|
|
29
|
-
setState(auth_state_1.createLoadingAuthState);
|
|
30
|
-
try {
|
|
31
|
-
const result = await (0, auth_operations_1.initializeFromStorage)(dependencies);
|
|
32
|
-
if (result) {
|
|
33
|
-
setState((0, auth_state_1.createAuthenticatedState)(result.user, result.tokens));
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
setState((0, auth_state_1.createUnauthenticatedState)());
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
setState((0, auth_state_1.createErrorState)((0, auth_state_1.createInitialAuthState)(), 'Failed to initialize authentication'));
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
initialize();
|
|
44
|
-
}, [dependencies, autoInitialize]);
|
|
45
|
-
// Authentication actions
|
|
46
|
-
const handleSignin = (0, react_1.useCallback)(async (credentials) => {
|
|
47
|
-
setState(prevState => (0, auth_state_1.createLoadingAuthState)(prevState));
|
|
48
|
-
try {
|
|
49
|
-
const result = await (0, auth_operations_1.signin)(credentials, dependencies);
|
|
50
|
-
setState((0, auth_state_1.createAuthenticatedState)(result.user, result.tokens));
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
const errorMessage = error instanceof Error ? error.message : 'Sign in failed';
|
|
54
|
-
setState(prevState => (0, auth_state_1.createErrorState)(prevState, errorMessage));
|
|
55
|
-
throw error;
|
|
56
|
-
}
|
|
57
|
-
}, [dependencies]);
|
|
58
|
-
const handleSignout = (0, react_1.useCallback)(async () => {
|
|
59
|
-
setState(prevState => (0, auth_state_1.createLoadingAuthState)(prevState));
|
|
60
|
-
try {
|
|
61
|
-
await (0, auth_operations_1.signout)(dependencies);
|
|
62
|
-
setState((0, auth_state_1.createUnauthenticatedState)());
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
// Even if signout fails, clear local state
|
|
66
|
-
setState((0, auth_state_1.createUnauthenticatedState)());
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
}, [dependencies]);
|
|
70
|
-
const handleSignup = (0, react_1.useCallback)(async (userData) => {
|
|
71
|
-
setState(prevState => (0, auth_state_1.createLoadingAuthState)(prevState));
|
|
72
|
-
try {
|
|
73
|
-
const result = await (0, auth_operations_1.signup)(userData, dependencies);
|
|
74
|
-
setState(prevState => ({ ...prevState, isLoading: false }));
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
const errorMessage = error instanceof Error ? error.message : 'Signup failed';
|
|
79
|
-
setState(prevState => (0, auth_state_1.createErrorState)(prevState, errorMessage));
|
|
80
|
-
return { success: false, message: errorMessage };
|
|
81
|
-
}
|
|
82
|
-
}, [dependencies]);
|
|
83
|
-
const handleRefreshTokens = (0, react_1.useCallback)(async () => {
|
|
84
|
-
if (!state.tokens) {
|
|
85
|
-
throw new Error('No tokens to refresh');
|
|
86
|
-
}
|
|
87
|
-
try {
|
|
88
|
-
const newTokens = await (0, auth_operations_1.refreshTokens)(state.tokens, dependencies);
|
|
89
|
-
setState(prevState => (0, auth_state_1.updateTokens)(prevState, newTokens));
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
// If refresh fails, sign out user
|
|
93
|
-
setState((0, auth_state_1.createUnauthenticatedState)());
|
|
94
|
-
throw error;
|
|
95
|
-
}
|
|
96
|
-
}, [state.tokens, dependencies]);
|
|
97
|
-
const handleVerifyEmail = (0, react_1.useCallback)(async (token) => {
|
|
98
|
-
setState(prevState => (0, auth_state_1.createLoadingAuthState)(prevState));
|
|
99
|
-
try {
|
|
100
|
-
const result = await (0, auth_operations_1.verifyEmail)({ token }, dependencies);
|
|
101
|
-
setState(prevState => ({ ...prevState, isLoading: false }));
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
const errorMessage = error instanceof Error ? error.message : 'Email verification failed';
|
|
106
|
-
setState(prevState => (0, auth_state_1.createErrorState)(prevState, errorMessage));
|
|
107
|
-
return { success: false, message: errorMessage };
|
|
108
|
-
}
|
|
109
|
-
}, [dependencies]);
|
|
110
|
-
const handleResendVerificationCode = (0, react_1.useCallback)(async () => {
|
|
111
|
-
setState(prevState => (0, auth_state_1.createLoadingAuthState)(prevState));
|
|
112
|
-
try {
|
|
113
|
-
const result = await (0, auth_operations_1.resendVerificationCode)(dependencies);
|
|
114
|
-
setState(prevState => ({ ...prevState, isLoading: false }));
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
const errorMessage = error instanceof Error ? error.message : 'Failed to resend verification code';
|
|
119
|
-
setState(prevState => (0, auth_state_1.createErrorState)(prevState, errorMessage));
|
|
120
|
-
return { success: false, message: errorMessage };
|
|
121
|
-
}
|
|
122
|
-
}, [dependencies]);
|
|
123
|
-
const handleClearError = (0, react_1.useCallback)(() => {
|
|
124
|
-
setState(prevState => (0, auth_state_1.clearError)(prevState));
|
|
125
|
-
}, []);
|
|
126
|
-
// Context value
|
|
127
|
-
const contextValue = {
|
|
128
|
-
state,
|
|
129
|
-
signin: handleSignin,
|
|
130
|
-
signout: handleSignout,
|
|
131
|
-
signup: handleSignup,
|
|
132
|
-
refreshTokens: handleRefreshTokens,
|
|
133
|
-
verifyEmail: handleVerifyEmail,
|
|
134
|
-
resendVerificationCode: handleResendVerificationCode,
|
|
135
|
-
clearError: handleClearError,
|
|
136
|
-
validateSigninCredentials: auth_operations_1.validateSigninCredentials,
|
|
137
|
-
validateSignupData: auth_operations_1.validateSignupData,
|
|
138
|
-
};
|
|
139
|
-
return ((0, jsx_runtime_1.jsx)(AuthContext.Provider, { value: contextValue, children: children }));
|
|
140
|
-
};
|
|
141
|
-
exports.AuthProvider = AuthProvider;
|
|
142
|
-
/**
|
|
143
|
-
* Hook to use authentication context
|
|
144
|
-
*
|
|
145
|
-
* @returns Authentication context value
|
|
146
|
-
* @throws Error if used outside AuthProvider
|
|
147
|
-
*/
|
|
148
|
-
const useAuth = () => {
|
|
149
|
-
const context = (0, react_1.useContext)(AuthContext);
|
|
150
|
-
if (!context) {
|
|
151
|
-
throw new Error('useAuth must be used within an AuthProvider');
|
|
152
|
-
}
|
|
153
|
-
return context;
|
|
154
|
-
};
|
|
155
|
-
exports.useAuth = useAuth;
|
|
156
|
-
/**
|
|
157
|
-
* Hook to get authentication state only (for components that only need to read state)
|
|
158
|
-
*/
|
|
159
|
-
const useAuthState = () => {
|
|
160
|
-
const { state } = (0, exports.useAuth)();
|
|
161
|
-
return state;
|
|
162
|
-
};
|
|
163
|
-
exports.useAuthState = useAuthState;
|
|
164
|
-
/**
|
|
165
|
-
* Hook for authentication actions only (for components that only need actions)
|
|
166
|
-
*/
|
|
167
|
-
const useAuthActions = () => {
|
|
168
|
-
const { signin, signout, signup, refreshTokens, verifyEmail, resendVerificationCode, clearError, validateSigninCredentials, validateSignupData, } = (0, exports.useAuth)();
|
|
169
|
-
return {
|
|
170
|
-
signin,
|
|
171
|
-
signout,
|
|
172
|
-
signup,
|
|
173
|
-
refreshTokens,
|
|
174
|
-
verifyEmail,
|
|
175
|
-
resendVerificationCode,
|
|
176
|
-
clearError,
|
|
177
|
-
validateSigninCredentials,
|
|
178
|
-
validateSignupData,
|
|
179
|
-
};
|
|
180
|
-
};
|
|
181
|
-
exports.useAuthActions = useAuthActions;
|
|
182
|
-
/**
|
|
183
|
-
* Higher-order component for components that require authentication
|
|
184
|
-
*/
|
|
185
|
-
const withAuth = (Component) => {
|
|
186
|
-
const AuthenticatedComponent = (props) => {
|
|
187
|
-
const { state } = (0, exports.useAuth)();
|
|
188
|
-
if (!state.isAuthenticated) {
|
|
189
|
-
return (0, jsx_runtime_1.jsx)("div", { children: "Please sign in to continue." });
|
|
190
|
-
}
|
|
191
|
-
return (0, jsx_runtime_1.jsx)(Component, { ...props });
|
|
192
|
-
};
|
|
193
|
-
AuthenticatedComponent.displayName = `withAuth(${Component.displayName || Component.name})`;
|
|
194
|
-
return AuthenticatedComponent;
|
|
195
|
-
};
|
|
196
|
-
exports.withAuth = withAuth;
|
|
197
|
-
const AuthGuard = ({ children, fallback = (0, jsx_runtime_1.jsx)("div", { children: "Access denied" }), requireAuth = true, requireVerification = false, }) => {
|
|
198
|
-
const { state } = (0, exports.useAuth)();
|
|
199
|
-
if (requireAuth && !state.isAuthenticated) {
|
|
200
|
-
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback });
|
|
201
|
-
}
|
|
202
|
-
if (requireVerification && state.user && !state.user.isVerified) {
|
|
203
|
-
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback });
|
|
204
|
-
}
|
|
205
|
-
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
206
|
-
};
|
|
207
|
-
exports.AuthGuard = AuthGuard;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Blueberry Dashboard Integration Example
|
|
3
|
-
*
|
|
4
|
-
* Demonstrates how to integrate the functional architecture with the Blueberry React dashboard.
|
|
5
|
-
* Clean, simple setup with pure functional services.
|
|
6
|
-
*/
|
|
7
|
-
import React from 'react';
|
|
8
|
-
export declare const setupBlueberryServices: () => {
|
|
9
|
-
services: import("../index").ServiceFactory;
|
|
10
|
-
};
|
|
11
|
-
export declare const BlueberryAuthProvider: React.FC<{
|
|
12
|
-
children: React.ReactNode;
|
|
13
|
-
}>;
|
|
14
|
-
export declare const BlueberryDashboard: React.FC;
|
|
15
|
-
export declare const BlueberryApp: React.FC;
|
|
16
|
-
export declare const enableFunctionalPortfolios: () => void;
|
|
17
|
-
export declare const getMigrationProgress: () => {
|
|
18
|
-
progress: number;
|
|
19
|
-
status: string;
|
|
20
|
-
};
|
|
21
|
-
//# sourceMappingURL=blueberry-integration.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blueberry-integration.d.ts","sourceRoot":"","sources":["../../src/integration/blueberry-integration.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,eAAO,MAAM,sBAAsB;;CAUlC,CAAC;AAGF,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAoBzE,CAAC;AAGF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAkHtC,CAAC;AAGF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAWhC,CAAC;AAGF,eAAO,MAAM,0BAA0B,YAEtC,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;CAEhC,CAAC"}
|