@umituz/react-native-design-system 2.8.7 → 2.8.8

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 (128) hide show
  1. package/package.json +5 -6
  2. package/src/device/infrastructure/repositories/LegacyDeviceIdRepository.ts +1 -1
  3. package/src/device/infrastructure/services/DeviceFeatureService.ts +1 -1
  4. package/src/exception/infrastructure/services/ExceptionLogger.ts +1 -1
  5. package/src/exception/infrastructure/storage/ExceptionStore.ts +1 -1
  6. package/src/exports/filesystem.ts +1 -0
  7. package/src/exports/storage.ts +1 -0
  8. package/src/filesystem/domain/constants/FileConstants.ts +20 -0
  9. package/src/filesystem/domain/entities/File.ts +20 -0
  10. package/src/filesystem/domain/types/FileTypes.ts +43 -0
  11. package/src/filesystem/domain/utils/FileUtils.ts +86 -0
  12. package/src/filesystem/index.ts +23 -0
  13. package/src/filesystem/infrastructure/services/FileSystemService.ts +45 -0
  14. package/src/filesystem/infrastructure/services/cache.service.ts +48 -0
  15. package/src/filesystem/infrastructure/services/directory.service.ts +66 -0
  16. package/src/filesystem/infrastructure/services/download.constants.ts +6 -0
  17. package/src/filesystem/infrastructure/services/download.service.ts +74 -0
  18. package/src/filesystem/infrastructure/services/download.types.ts +7 -0
  19. package/src/filesystem/infrastructure/services/encoding.service.ts +25 -0
  20. package/src/filesystem/infrastructure/services/file-info.service.ts +52 -0
  21. package/src/filesystem/infrastructure/services/file-manager.service.ts +81 -0
  22. package/src/filesystem/infrastructure/services/file-path.service.ts +22 -0
  23. package/src/filesystem/infrastructure/services/file-reader.service.ts +52 -0
  24. package/src/filesystem/infrastructure/services/file-writer.service.ts +32 -0
  25. package/src/filesystem/infrastructure/utils/blob.utils.ts +20 -0
  26. package/src/image/infrastructure/services/ImageStorageService.ts +1 -1
  27. package/src/index.ts +9 -0
  28. package/src/molecules/alerts/AlertStore.ts +1 -1
  29. package/src/molecules/calendar/infrastructure/storage/EventActions.ts +1 -1
  30. package/src/molecules/calendar/infrastructure/stores/storageAdapter.ts +1 -1
  31. package/src/offline/infrastructure/storage/OfflineStore.ts +1 -1
  32. package/src/onboarding/infrastructure/storage/OnboardingStore.ts +2 -2
  33. package/src/onboarding/infrastructure/storage/__tests__/OnboardingStore.test.ts +1 -1
  34. package/src/onboarding/infrastructure/storage/actions/answerActions.ts +1 -1
  35. package/src/onboarding/infrastructure/storage/actions/storageHelpers.ts +1 -1
  36. package/src/storage/README.md +185 -0
  37. package/src/storage/__tests__/integration.test.ts +391 -0
  38. package/src/storage/__tests__/mocks/asyncStorage.mock.ts +52 -0
  39. package/src/storage/__tests__/performance.test.tsx +352 -0
  40. package/src/storage/__tests__/setup.ts +63 -0
  41. package/src/storage/application/README.md +158 -0
  42. package/src/storage/application/ports/IStorageRepository.ts +61 -0
  43. package/src/storage/application/ports/README.md +127 -0
  44. package/src/storage/cache/README.md +154 -0
  45. package/src/storage/cache/__tests__/PerformanceAndMemory.test.ts +387 -0
  46. package/src/storage/cache/__tests__/setup.ts +19 -0
  47. package/src/storage/cache/domain/Cache.ts +146 -0
  48. package/src/storage/cache/domain/CacheManager.md +83 -0
  49. package/src/storage/cache/domain/CacheManager.ts +48 -0
  50. package/src/storage/cache/domain/CacheStatsTracker.md +169 -0
  51. package/src/storage/cache/domain/CacheStatsTracker.ts +49 -0
  52. package/src/storage/cache/domain/CachedValue.md +97 -0
  53. package/src/storage/cache/domain/ErrorHandler.md +99 -0
  54. package/src/storage/cache/domain/ErrorHandler.ts +42 -0
  55. package/src/storage/cache/domain/PatternMatcher.md +122 -0
  56. package/src/storage/cache/domain/PatternMatcher.ts +30 -0
  57. package/src/storage/cache/domain/README.md +118 -0
  58. package/src/storage/cache/domain/__tests__/Cache.test.ts +293 -0
  59. package/src/storage/cache/domain/__tests__/CacheManager.test.ts +276 -0
  60. package/src/storage/cache/domain/__tests__/ErrorHandler.test.ts +303 -0
  61. package/src/storage/cache/domain/__tests__/PatternMatcher.test.ts +261 -0
  62. package/src/storage/cache/domain/strategies/EvictionStrategy.ts +9 -0
  63. package/src/storage/cache/domain/strategies/FIFOStrategy.ts +12 -0
  64. package/src/storage/cache/domain/strategies/LFUStrategy.ts +22 -0
  65. package/src/storage/cache/domain/strategies/LRUStrategy.ts +22 -0
  66. package/src/storage/cache/domain/strategies/README.md +117 -0
  67. package/src/storage/cache/domain/strategies/TTLStrategy.ts +23 -0
  68. package/src/storage/cache/domain/strategies/__tests__/EvictionStrategies.test.ts +293 -0
  69. package/src/storage/cache/domain/types/Cache.ts +28 -0
  70. package/src/storage/cache/domain/types/README.md +107 -0
  71. package/src/storage/cache/index.ts +28 -0
  72. package/src/storage/cache/infrastructure/README.md +126 -0
  73. package/src/storage/cache/infrastructure/TTLCache.ts +103 -0
  74. package/src/storage/cache/infrastructure/__tests__/TTLCache.test.ts +303 -0
  75. package/src/storage/cache/presentation/README.md +123 -0
  76. package/src/storage/cache/presentation/__tests__/ReactHooks.test.ts +514 -0
  77. package/src/storage/cache/presentation/useCache.ts +76 -0
  78. package/src/storage/cache/presentation/useCachedValue.ts +88 -0
  79. package/src/storage/cache/types.d.ts +3 -0
  80. package/src/storage/domain/README.md +128 -0
  81. package/src/storage/domain/constants/CacheDefaults.ts +64 -0
  82. package/src/storage/domain/constants/README.md +105 -0
  83. package/src/storage/domain/entities/CachedValue.ts +86 -0
  84. package/src/storage/domain/entities/README.md +109 -0
  85. package/src/storage/domain/entities/StorageResult.ts +75 -0
  86. package/src/storage/domain/entities/__tests__/CachedValue.test.ts +149 -0
  87. package/src/storage/domain/entities/__tests__/StorageResult.test.ts +122 -0
  88. package/src/storage/domain/errors/README.md +126 -0
  89. package/src/storage/domain/errors/StorageError.ts +81 -0
  90. package/src/storage/domain/errors/__tests__/StorageError.test.ts +127 -0
  91. package/src/storage/domain/factories/README.md +138 -0
  92. package/src/storage/domain/factories/StoreFactory.ts +59 -0
  93. package/src/storage/domain/types/README.md +522 -0
  94. package/src/storage/domain/types/Store.ts +44 -0
  95. package/src/storage/domain/utils/CacheKeyGenerator.ts +66 -0
  96. package/src/storage/domain/utils/README.md +127 -0
  97. package/src/storage/domain/utils/__tests__/devUtils.test.ts +97 -0
  98. package/src/storage/domain/utils/devUtils.ts +37 -0
  99. package/src/storage/domain/value-objects/README.md +120 -0
  100. package/src/storage/domain/value-objects/StorageKey.ts +60 -0
  101. package/src/storage/index.ts +175 -0
  102. package/src/storage/infrastructure/README.md +165 -0
  103. package/src/storage/infrastructure/adapters/README.md +175 -0
  104. package/src/storage/infrastructure/adapters/StorageService.md +103 -0
  105. package/src/storage/infrastructure/adapters/StorageService.ts +49 -0
  106. package/src/storage/infrastructure/repositories/AsyncStorageRepository.ts +98 -0
  107. package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +100 -0
  108. package/src/storage/infrastructure/repositories/BatchStorageOperations.ts +42 -0
  109. package/src/storage/infrastructure/repositories/README.md +121 -0
  110. package/src/storage/infrastructure/repositories/StringStorageOperations.ts +44 -0
  111. package/src/storage/infrastructure/repositories/__tests__/AsyncStorageRepository.test.ts +170 -0
  112. package/src/storage/infrastructure/repositories/__tests__/BaseStorageOperations.test.ts +201 -0
  113. package/src/storage/presentation/README.md +181 -0
  114. package/src/storage/presentation/hooks/CacheStorageOperations.ts +94 -0
  115. package/src/storage/presentation/hooks/README.md +128 -0
  116. package/src/storage/presentation/hooks/__tests__/usePersistentCache.test.ts +405 -0
  117. package/src/storage/presentation/hooks/__tests__/useStorage.test.ts +247 -0
  118. package/src/storage/presentation/hooks/__tests__/useStorageState.test.ts +293 -0
  119. package/src/storage/presentation/hooks/useCacheState.ts +53 -0
  120. package/src/storage/presentation/hooks/usePersistentCache.ts +154 -0
  121. package/src/storage/presentation/hooks/useStorage.ts +102 -0
  122. package/src/storage/presentation/hooks/useStorageState.ts +71 -0
  123. package/src/storage/presentation/hooks/useStore.ts +15 -0
  124. package/src/storage/types/README.md +103 -0
  125. package/src/theme/infrastructure/globalThemeStore.ts +1 -1
  126. package/src/theme/infrastructure/storage/ThemeStorage.ts +1 -1
  127. package/src/theme/infrastructure/stores/themeStore.ts +1 -1
  128. package/src/utilities/sharing/infrastructure/services/SharingService.ts +1 -1
@@ -0,0 +1,149 @@
1
+ /**
2
+ * CachedValue Entity Tests
3
+ *
4
+ * Unit tests for CachedValue entity
5
+ */
6
+
7
+ import {
8
+ createCachedValue,
9
+ isCacheExpired,
10
+ getRemainingTTL,
11
+ getCacheAge
12
+ } from '../../domain/entities/CachedValue';
13
+
14
+ describe('CachedValue Entity', () => {
15
+ const mockNow = 1000000;
16
+
17
+ beforeEach(() => {
18
+ jest.spyOn(Date, 'now').mockReturnValue(mockNow);
19
+ });
20
+
21
+ afterEach(() => {
22
+ jest.restoreAllMocks();
23
+ });
24
+
25
+ describe('createCachedValue', () => {
26
+ it('should create cached value with default values', () => {
27
+ const data = { test: 'value' };
28
+ const cached = createCachedValue(data);
29
+
30
+ expect(cached.value).toBe(data);
31
+ expect(cached.timestamp).toBe(mockNow);
32
+ expect(cached.ttl).toBeDefined();
33
+ expect(cached.version).toBeUndefined();
34
+ });
35
+
36
+ it('should create cached value with custom TTL', () => {
37
+ const data = { test: 'value' };
38
+ const ttl = 60000; // 1 minute
39
+ const cached = createCachedValue(data, ttl);
40
+
41
+ expect(cached.value).toBe(data);
42
+ expect(cached.timestamp).toBe(mockNow);
43
+ expect(cached.ttl).toBe(ttl);
44
+ });
45
+
46
+ it('should create cached value with version', () => {
47
+ const data = { test: 'value' };
48
+ const version = 2;
49
+ const cached = createCachedValue(data, undefined, version);
50
+
51
+ expect(cached.value).toBe(data);
52
+ expect(cached.timestamp).toBe(mockNow);
53
+ expect(cached.version).toBe(version);
54
+ });
55
+ });
56
+
57
+ describe('isCacheExpired', () => {
58
+ it('should return false for fresh cache', () => {
59
+ const data = { test: 'value' };
60
+ const ttl = 60000; // 1 minute
61
+ const cached = createCachedValue(data, ttl);
62
+
63
+ expect(isCacheExpired(cached)).toBe(false);
64
+ });
65
+
66
+ it('should return true for expired cache', () => {
67
+ const data = { test: 'value' };
68
+ const ttl = 1000; // 1 second
69
+ const cached = createCachedValue(data, ttl, mockNow - 2000); // Created 2 seconds ago
70
+
71
+ expect(isCacheExpired(cached)).toBe(true);
72
+ });
73
+
74
+ it('should handle version mismatch', () => {
75
+ const data = { test: 'value' };
76
+ const cached = createCachedValue(data, 60000, 1);
77
+ const currentVersion = 2;
78
+
79
+ expect(isCacheExpired(cached, currentVersion)).toBe(true);
80
+ });
81
+
82
+ it('should return false when version matches', () => {
83
+ const data = { test: 'value' };
84
+ const cached = createCachedValue(data, 60000, 1);
85
+ const currentVersion = 1;
86
+
87
+ expect(isCacheExpired(cached, currentVersion)).toBe(false);
88
+ });
89
+ });
90
+
91
+ describe('getRemainingTTL', () => {
92
+ it('should return remaining TTL for fresh cache', () => {
93
+ const data = { test: 'value' };
94
+ const ttl = 60000; // 1 minute
95
+ const cached = createCachedValue(data, ttl, mockNow - 30000); // Created 30 seconds ago
96
+
97
+ const remaining = getRemainingTTL(cached);
98
+ expect(remaining).toBe(30000); // 30 seconds remaining
99
+ });
100
+
101
+ it('should return 0 for expired cache', () => {
102
+ const data = { test: 'value' };
103
+ const ttl = 1000; // 1 second
104
+ const cached = createCachedValue(data, ttl, mockNow - 2000); // Created 2 seconds ago
105
+
106
+ const remaining = getRemainingTTL(cached);
107
+ expect(remaining).toBe(0);
108
+ });
109
+
110
+ it('should handle missing TTL', () => {
111
+ const data = { test: 'value' };
112
+ const cached = createCachedValue(data);
113
+
114
+ const remaining = getRemainingTTL(cached);
115
+ expect(remaining).toBeGreaterThan(0);
116
+ });
117
+ });
118
+
119
+ describe('getCacheAge', () => {
120
+ it('should return correct age', () => {
121
+ const data = { test: 'value' };
122
+ const age = 30000; // 30 seconds
123
+ const cached = createCachedValue(data, undefined, undefined, mockNow - age);
124
+
125
+ const cacheAge = getCacheAge(cached);
126
+ expect(cacheAge).toBe(age);
127
+ });
128
+
129
+ it('should return 0 for new cache', () => {
130
+ const data = { test: 'value' };
131
+ const cached = createCachedValue(data);
132
+
133
+ const cacheAge = getCacheAge(cached);
134
+ expect(cacheAge).toBe(0);
135
+ });
136
+ });
137
+
138
+ describe('Immutability', () => {
139
+ it('should create immutable cached value', () => {
140
+ const data = { test: 'value' };
141
+ const cached = createCachedValue(data);
142
+
143
+ // Attempt to modify
144
+ (cached as any).value = { modified: true };
145
+
146
+ expect(cached.value).toEqual(data);
147
+ });
148
+ });
149
+ });
@@ -0,0 +1,122 @@
1
+ /**
2
+ * StorageResult Entity Tests
3
+ *
4
+ * Unit tests for StorageResult entity
5
+ */
6
+
7
+ import { success, failure, unwrap, map, isSuccess, isFailure } from '../../domain/entities/StorageResult';
8
+ import { StorageError } from '../../domain/errors/StorageError';
9
+
10
+ describe('StorageResult Entity', () => {
11
+ describe('success', () => {
12
+ it('should create a successful result', () => {
13
+ const data = { test: 'value' };
14
+ const result = success(data);
15
+
16
+ expect(result.success).toBe(true);
17
+ expect(result.data).toBe(data);
18
+ expect(result.error).toBeUndefined();
19
+ });
20
+ });
21
+
22
+ describe('failure', () => {
23
+ it('should create a failure result', () => {
24
+ const error = new StorageError('test-key', new Error('Test error'));
25
+ const defaultValue = 'default';
26
+ const result = failure(error, defaultValue);
27
+
28
+ expect(result.success).toBe(false);
29
+ expect(result.data).toBe(defaultValue);
30
+ expect(result.error).toBe(error);
31
+ });
32
+ });
33
+
34
+ describe('unwrap', () => {
35
+ it('should return data for successful result', () => {
36
+ const data = { test: 'value' };
37
+ const result = success(data);
38
+ const defaultValue = 'default';
39
+
40
+ const unwrapped = unwrap(result, defaultValue);
41
+
42
+ expect(unwrapped).toBe(data);
43
+ });
44
+
45
+ it('should return default value for failure result', () => {
46
+ const error = new StorageError('test-key', new Error('Test error'));
47
+ const defaultValue = 'default';
48
+ const result = failure(error, defaultValue);
49
+
50
+ const unwrapped = unwrap(result, defaultValue);
51
+
52
+ expect(unwrapped).toBe(defaultValue);
53
+ });
54
+ });
55
+
56
+ describe('map', () => {
57
+ it('should map successful result', () => {
58
+ const data = { count: 1 };
59
+ const result = success(data);
60
+ const mapper = (value: typeof data) => ({ ...value, count: value.count + 1 });
61
+
62
+ const mapped = map(result, mapper);
63
+
64
+ expect(mapped.success).toBe(true);
65
+ expect(mapped.data).toEqual({ count: 2 });
66
+ });
67
+
68
+ it('should not map failure result', () => {
69
+ const error = new StorageError('test-key', new Error('Test error'));
70
+ const defaultValue = { count: 0 };
71
+ const result = failure(error, defaultValue);
72
+ const mapper = jest.fn();
73
+
74
+ const mapped = map(result, mapper);
75
+
76
+ expect(mapped.success).toBe(false);
77
+ expect(mapper).not.toHaveBeenCalled();
78
+ });
79
+ });
80
+
81
+ describe('isSuccess', () => {
82
+ it('should return true for successful result', () => {
83
+ const result = success('test');
84
+ expect(isSuccess(result)).toBe(true);
85
+ });
86
+
87
+ it('should return false for failure result', () => {
88
+ const error = new StorageError('test-key', new Error('Test error'));
89
+ const result = failure(error);
90
+ expect(isSuccess(result)).toBe(false);
91
+ });
92
+ });
93
+
94
+ describe('isFailure', () => {
95
+ it('should return false for successful result', () => {
96
+ const result = success('test');
97
+ expect(isFailure(result)).toBe(false);
98
+ });
99
+
100
+ it('should return true for failure result', () => {
101
+ const error = new StorageError('test-key', new Error('Test error'));
102
+ const result = failure(error);
103
+ expect(isFailure(result)).toBe(true);
104
+ });
105
+ });
106
+
107
+ describe('Type Safety', () => {
108
+ it('should maintain type information', () => {
109
+ interface TestData {
110
+ id: number;
111
+ name: string;
112
+ }
113
+
114
+ const data: TestData = { id: 1, name: 'test' };
115
+ const result = success<TestData>(data);
116
+
117
+ // TypeScript should infer the type correctly
118
+ const typedData: TestData = result.data;
119
+ expect(typedData).toEqual(data);
120
+ });
121
+ });
122
+ });
@@ -0,0 +1,126 @@
1
+ # Storage Errors
2
+
3
+ Error classes and error handling strategies for storage operations.
4
+
5
+ ## Overview
6
+
7
+ Hierarchical error classes for storage operations with context preservation. Located at `src/domain/errors/`.
8
+
9
+ ## Strategies
10
+
11
+ ### Error Hierarchy
12
+ - Use StorageError as base class for all storage errors
13
+ - Create specific error types for different operations
14
+ - Preserve error context (key, operation, cause)
15
+ - Enable error type checking with instanceof
16
+
17
+ ### Error Categories
18
+ - StorageReadError for read failures
19
+ - StorageWriteError for write failures
20
+ - StorageDeleteError for delete failures
21
+ - StorageSerializationError for serialization failures
22
+ - StorageDeserializationError for parsing failures
23
+
24
+ ### Error Handling Strategy
25
+ - Use Result pattern instead of throwing exceptions
26
+ - Preserve original error as cause property
27
+ - Include error codes for programmatic handling
28
+ - Log errors with full context
29
+
30
+ ### Error Recovery
31
+ - Implement retry logic for transient failures
32
+ - Provide fallback values for graceful degradation
33
+ - Clear corrupted data when appropriate
34
+ - Alert monitoring systems for critical errors
35
+
36
+ ## Restrictions
37
+
38
+ ### Error Creation
39
+ - DO NOT throw generic Error class
40
+ - DO NOT lose error context when wrapping
41
+ - DO NOT create error types without clear purpose
42
+ - DO NOT use strings for error codes
43
+
44
+ ### Error Handling
45
+ - DO NOT catch and ignore errors silently
46
+ - DO NOT suppress error logging in production
47
+ - DO NOT retry indefinitely on persistent failures
48
+ - DO NOT expose sensitive data in error messages
49
+
50
+ ### Error Types
51
+ - DO NOT mix different error categories
52
+ - DO NOT create circular error hierarchies
53
+ - DO NOT omit error code from custom errors
54
+ - DO NOT cause infinite error loops
55
+
56
+ ## Rules
57
+
58
+ ### Error Base Class
59
+ - MUST extend Error class
60
+ - MUST include code property (string)
61
+ - MUST preserve stack trace
62
+ - MUST accept cause parameter for wrapping
63
+ - MUST include message parameter
64
+
65
+ ### Specific Error Types
66
+ - MUST extend StorageError base class
67
+ - MUST include key property for storage errors
68
+ - MUST include cause property when wrapping
69
+ - MUST use specific error codes
70
+ - MUST set appropriate error name
71
+
72
+ ### Error Codes
73
+ - MUST use format: CATEGORY_ERROR (e.g., STORAGE_READ_ERROR)
74
+ - MUST be unique across error types
75
+ - MUST be descriptive and searchable
76
+ - MUST follow naming convention
77
+ - MUST be documented
78
+
79
+ ### Error Context
80
+ - MUST include storage key in storage errors
81
+ - MUST include original operation type
82
+ - MUST attach cause error when wrapping
83
+ - MUST preserve stack trace
84
+ - MUST include timestamp for debugging
85
+
86
+ ### Error Handling Patterns
87
+ - MUST use try-catch for all storage operations
88
+ - MUST check error types with instanceof
89
+ - MUST log errors with full context
90
+ - MUST provide error recovery where possible
91
+ - MUST not expose sensitive data
92
+
93
+ ### Custom Error Creation
94
+ - MUST extend StorageError for custom errors
95
+ - MUST provide unique error code
96
+ - MUST include all required context
97
+ - MUST document error purpose
98
+ - MUST follow naming conventions
99
+
100
+ ### Error Logging
101
+ - MUST log error code and message
102
+ - MUST log error context (key, operation)
103
+ - MUST log cause error if present
104
+ - MUST log stack trace in development
105
+ - MUST not log sensitive data
106
+
107
+ ### Error Testing
108
+ - MUST test error creation
109
+ - MUST test error type checking
110
+ - MUST test error context preservation
111
+ - MUST test error logging
112
+ - MUST test error recovery logic
113
+
114
+ ### Type Safety
115
+ - MUST use instanceof for type checking
116
+ - MUST use type guards where appropriate
117
+ - MUST enforce error codes as literal types
118
+ - MUST provide TypeScript types
119
+ - MUST not use `any` for error types
120
+
121
+ ### Error Recovery
122
+ - MUST implement retry limits
123
+ - MUST provide fallback strategies
124
+ - MUST clear corrupted data when detected
125
+ - MUST alert on critical failures
126
+ - MUST document recovery behavior
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Storage Error Types
3
+ *
4
+ * Domain-Driven Design: Domain errors for storage operations
5
+ * Typed errors for better error handling and debugging
6
+ */
7
+
8
+ /**
9
+ * Base Storage Error
10
+ */
11
+ export class StorageError extends Error {
12
+ constructor(message: string, public readonly key?: string) {
13
+ super(message);
14
+ this.name = 'StorageError';
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Storage Read Error
20
+ */
21
+ export class StorageReadError extends StorageError {
22
+ public readonly cause?: unknown;
23
+
24
+ constructor(key: string, cause?: unknown) {
25
+ super(`Failed to read from storage: ${key}`, key);
26
+ this.name = 'StorageReadError';
27
+ this.cause = cause;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Storage Write Error
33
+ */
34
+ export class StorageWriteError extends StorageError {
35
+ public readonly cause?: unknown;
36
+
37
+ constructor(key: string, cause?: unknown) {
38
+ super(`Failed to write to storage: ${key}`, key);
39
+ this.name = 'StorageWriteError';
40
+ this.cause = cause;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Storage Delete Error
46
+ */
47
+ export class StorageDeleteError extends StorageError {
48
+ public readonly cause?: unknown;
49
+
50
+ constructor(key: string, cause?: unknown) {
51
+ super(`Failed to delete from storage: ${key}`, key);
52
+ this.name = 'StorageDeleteError';
53
+ this.cause = cause;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Storage Serialization Error
59
+ */
60
+ export class StorageSerializationError extends StorageError {
61
+ public readonly cause?: unknown;
62
+
63
+ constructor(key: string, cause?: unknown) {
64
+ super(`Failed to serialize data for key: ${key}`, key);
65
+ this.name = 'StorageSerializationError';
66
+ this.cause = cause;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Storage Deserialization Error
72
+ */
73
+ export class StorageDeserializationError extends StorageError {
74
+ public readonly cause?: unknown;
75
+
76
+ constructor(key: string, cause?: unknown) {
77
+ super(`Failed to deserialize data for key: ${key}`, key);
78
+ this.name = 'StorageDeserializationError';
79
+ this.cause = cause;
80
+ }
81
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * StorageError Tests
3
+ *
4
+ * Unit tests for StorageError classes
5
+ */
6
+
7
+ import {
8
+ StorageError,
9
+ StorageReadError,
10
+ StorageWriteError,
11
+ StorageDeleteError,
12
+ StorageSerializationError,
13
+ StorageDeserializationError,
14
+ } from '../../domain/errors/StorageError';
15
+
16
+ describe('StorageError Classes', () => {
17
+ describe('StorageError', () => {
18
+ it('should create base storage error', () => {
19
+ const key = 'test-key';
20
+ const cause = new Error('Original error');
21
+ const error = new StorageError(key, cause);
22
+
23
+ expect(error.key).toBe(key);
24
+ expect(error.cause).toBe(cause);
25
+ expect(error.name).toBe('StorageError');
26
+ expect(error.message).toContain(key);
27
+ });
28
+
29
+ it('should serialize error details', () => {
30
+ const key = 'test-key';
31
+ const cause = new Error('Original error');
32
+ const error = new StorageError(key, cause);
33
+
34
+ const serialized = JSON.stringify(error);
35
+ const parsed = JSON.parse(serialized);
36
+
37
+ expect(parsed.key).toBe(key);
38
+ expect(parsed.message).toContain(key);
39
+ });
40
+ });
41
+
42
+ describe('StorageReadError', () => {
43
+ it('should create read error', () => {
44
+ const key = 'test-key';
45
+ const cause = new Error('Read failed');
46
+ const error = new StorageReadError(key, cause);
47
+
48
+ expect(error.key).toBe(key);
49
+ expect(error.cause).toBe(cause);
50
+ expect(error.name).toBe('StorageReadError');
51
+ expect(error.message).toContain('read');
52
+ });
53
+ });
54
+
55
+ describe('StorageWriteError', () => {
56
+ it('should create write error', () => {
57
+ const key = 'test-key';
58
+ const cause = new Error('Write failed');
59
+ const error = new StorageWriteError(key, cause);
60
+
61
+ expect(error.key).toBe(key);
62
+ expect(error.cause).toBe(cause);
63
+ expect(error.name).toBe('StorageWriteError');
64
+ expect(error.message).toContain('write');
65
+ });
66
+ });
67
+
68
+ describe('StorageDeleteError', () => {
69
+ it('should create delete error', () => {
70
+ const key = 'test-key';
71
+ const cause = new Error('Delete failed');
72
+ const error = new StorageDeleteError(key, cause);
73
+
74
+ expect(error.key).toBe(key);
75
+ expect(error.cause).toBe(cause);
76
+ expect(error.name).toBe('StorageDeleteError');
77
+ expect(error.message).toContain('delete');
78
+ });
79
+ });
80
+
81
+ describe('StorageSerializationError', () => {
82
+ it('should create serialization error', () => {
83
+ const key = 'test-key';
84
+ const cause = new Error('Serialization failed');
85
+ const error = new StorageSerializationError(key, cause);
86
+
87
+ expect(error.key).toBe(key);
88
+ expect(error.cause).toBe(cause);
89
+ expect(error.name).toBe('StorageSerializationError');
90
+ expect(error.message).toContain('serialize');
91
+ });
92
+ });
93
+
94
+ describe('StorageDeserializationError', () => {
95
+ it('should create deserialization error', () => {
96
+ const key = 'test-key';
97
+ const cause = new Error('Deserialization failed');
98
+ const error = new StorageDeserializationError(key, cause);
99
+
100
+ expect(error.key).toBe(key);
101
+ expect(error.cause).toBe(cause);
102
+ expect(error.name).toBe('StorageDeserializationError');
103
+ expect(error.message).toContain('deserialize');
104
+ });
105
+ });
106
+
107
+ describe('Error Inheritance', () => {
108
+ it('should maintain error chain', () => {
109
+ const key = 'test-key';
110
+ const cause = new Error('Original error');
111
+ const error = new StorageReadError(key, cause);
112
+
113
+ expect(error instanceof Error).toBe(true);
114
+ expect(error instanceof StorageError).toBe(true);
115
+ expect(error instanceof StorageReadError).toBe(true);
116
+ });
117
+
118
+ it('should preserve stack trace', () => {
119
+ const key = 'test-key';
120
+ const cause = new Error('Original error');
121
+ const error = new StorageReadError(key, cause);
122
+
123
+ expect(error.stack).toBeDefined();
124
+ expect(error.stack).toContain('StorageReadError');
125
+ });
126
+ });
127
+ });