@umituz/react-native-ai-fal-provider 3.2.52 → 3.2.54

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 (27) hide show
  1. package/package.json +1 -1
  2. package/src/domain/services/ErrorClassificationService.ts +201 -0
  3. package/src/domain/services/ImageProcessingService.ts +89 -0
  4. package/src/domain/services/PricingService.ts +101 -0
  5. package/src/domain/services/ValidationService.ts +132 -0
  6. package/src/domain/services/index.ts +13 -0
  7. package/src/index.ts +24 -22
  8. package/src/infrastructure/utils/fal-error-handler.util.ts +14 -146
  9. package/src/infrastructure/utils/fal-storage.util.ts +2 -3
  10. package/src/infrastructure/utils/helpers/index.ts +2 -4
  11. package/src/infrastructure/utils/image-helpers.util.ts +13 -27
  12. package/src/infrastructure/utils/input-preprocessor.util.ts +6 -12
  13. package/src/infrastructure/utils/input-validator.util.ts +17 -156
  14. package/src/infrastructure/utils/pricing/fal-pricing.util.ts +26 -53
  15. package/src/infrastructure/utils/type-guards/index.ts +2 -2
  16. package/src/shared/helpers.ts +149 -0
  17. package/src/shared/index.ts +8 -0
  18. package/src/shared/type-guards.ts +122 -0
  19. package/src/shared/validators.ts +281 -0
  20. package/src/infrastructure/utils/helpers/calculation-helpers.util.ts +0 -21
  21. package/src/infrastructure/utils/helpers/error-helpers.util.ts +0 -65
  22. package/src/infrastructure/utils/helpers/object-helpers.util.ts +0 -44
  23. package/src/infrastructure/utils/helpers/timing-helpers.util.ts +0 -11
  24. package/src/infrastructure/utils/type-guards/model-type-guards.util.ts +0 -56
  25. package/src/infrastructure/utils/type-guards/validation-guards.util.ts +0 -101
  26. package/src/infrastructure/utils/validators/data-uri-validator.util.ts +0 -91
  27. package/src/infrastructure/utils/validators/string-validator.util.ts +0 -64
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Shared Helper Utilities
3
+ * Consolidated helpers for error handling, object manipulation, timing, and calculations
4
+ *
5
+ * This file consolidates functionality from:
6
+ * - error-helpers.util.ts
7
+ * - object-helpers.util.ts
8
+ * - timing-helpers.util.ts
9
+ * - calculation-helpers.util.ts
10
+ */
11
+
12
+ // ─── Error Helpers ─────────────────────────────────────────────────────────────
13
+
14
+ /**
15
+ * Extract error message from any error type
16
+ * Handles Error instances, strings, and unknown types
17
+ *
18
+ * @param error - The error to extract message from
19
+ * @returns The error message as a string
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * try {
24
+ * await riskyOperation();
25
+ * } catch (error) {
26
+ * console.error('Operation failed:', getErrorMessage(error));
27
+ * }
28
+ * ```
29
+ */
30
+ export function getErrorMessage(error: unknown): string {
31
+ return error instanceof Error ? error.message : String(error);
32
+ }
33
+
34
+ /**
35
+ * Extract error message with fallback
36
+ * Returns fallback if error message is empty or whitespace-only
37
+ *
38
+ * @param error - The error to extract message from
39
+ * @param fallback - Fallback message if error message is empty
40
+ * @returns The error message or fallback
41
+ */
42
+ export function getErrorMessageOr(error: unknown, fallback: string): string {
43
+ const message = getErrorMessage(error);
44
+ return message && message.trim().length > 0 ? message : fallback;
45
+ }
46
+
47
+ /**
48
+ * Create error message with context prefix
49
+ * Useful for adding operation context to error messages
50
+ *
51
+ * @param error - The error to extract message from
52
+ * @param context - Context to prepend to the error message
53
+ * @returns Formatted error message with context
54
+ */
55
+ export function formatErrorMessage(error: unknown, context: string): string {
56
+ return `${context}: ${getErrorMessage(error)}`;
57
+ }
58
+
59
+ // ─── Object Helpers ───────────────────────────────────────────────────────────
60
+
61
+ /**
62
+ * Build error message with context
63
+ *
64
+ * @param type - Error type or category
65
+ * @param context - Object containing key-value pairs for context
66
+ * @returns Formatted error message string
67
+ */
68
+ export function buildErrorMessage(
69
+ type: string,
70
+ context: Record<string, unknown>
71
+ ): string {
72
+ const contextStr = Object.entries(context)
73
+ .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
74
+ .join(", ");
75
+ return `${type}${contextStr ? ` (${contextStr})` : ""}`;
76
+ }
77
+
78
+ /**
79
+ * Check if value is defined (not null or undefined)
80
+ *
81
+ * @param value - Value to check
82
+ * @returns Type guard indicating value is not null/undefined
83
+ */
84
+ export function isDefined<T>(value: T | null | undefined): value is T {
85
+ return value !== null && value !== undefined;
86
+ }
87
+
88
+ /**
89
+ * Filter out null and undefined values from object
90
+ *
91
+ * @param obj - Object to filter
92
+ * @returns New object with null/undefined values removed
93
+ */
94
+ export function removeNullish<T extends Record<string, unknown>>(
95
+ obj: T
96
+ ): Partial<T> {
97
+ return Object.fromEntries(
98
+ Object.entries(obj).filter(([_, value]) => isDefined(value))
99
+ ) as Partial<T>;
100
+ }
101
+
102
+ /**
103
+ * Generate unique ID with optional prefix
104
+ *
105
+ * @param prefix - Optional prefix for the ID
106
+ * @returns Unique identifier string
107
+ */
108
+ export function generateUniqueId(prefix: string = ""): string {
109
+ const timestamp = Date.now().toString(36);
110
+ const randomStr = Math.random().toString(36).substring(2, 9);
111
+ return prefix ? `${prefix}_${timestamp}${randomStr}` : `${timestamp}${randomStr}`;
112
+ }
113
+
114
+ // ─── Timing Helpers ───────────────────────────────────────────────────────────
115
+
116
+ /**
117
+ * Sleep for specified milliseconds
118
+ *
119
+ * @param ms - Milliseconds to sleep
120
+ * @returns Promise that resolves after delay
121
+ */
122
+ export function sleep(ms: number): Promise<void> {
123
+ return new Promise((resolve) => setTimeout(resolve, ms));
124
+ }
125
+
126
+ // ─── Calculation Helpers ──────────────────────────────────────────────────────
127
+
128
+ /**
129
+ * Calculate elapsed time in milliseconds from a start timestamp
130
+ *
131
+ * @param startTime - Start timestamp in milliseconds
132
+ * @returns Elapsed time in milliseconds
133
+ */
134
+ export function getElapsedTime(startTime: number): number {
135
+ return Date.now() - startTime;
136
+ }
137
+
138
+ /**
139
+ * Calculate actual file size from base64 string
140
+ * Base64 encoding inflates size by ~33%, so actual size is ~75% of base64 length
141
+ *
142
+ * @param base64String - Base64 encoded string
143
+ * @returns Actual size in kilobytes
144
+ */
145
+ export function getActualSizeKB(base64String: string): number {
146
+ const base64SizeKB = Math.round(base64String.length / 1024);
147
+ // Base64 inflates by ~33%, so actual size is ~75%
148
+ return Math.round(base64SizeKB * 0.75);
149
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared Utilities - Public API
3
+ * Consolidated helpers, validators, and type guards
4
+ */
5
+
6
+ export * from "./helpers";
7
+ export * from "./validators";
8
+ export * from "./type-guards";
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Shared Type Guards
3
+ * Runtime type checking for model types, error types, and other domain types
4
+ *
5
+ * This file consolidates functionality from:
6
+ * - model-type-guards.util.ts
7
+ * - validation-guards.util.ts (type guard portions)
8
+ */
9
+
10
+ import type { FalModelType } from "../domain/entities/fal.types";
11
+ import type { ModelType } from "../domain/types/model-selection.types";
12
+ import { FalErrorType } from "../domain/entities/error.types";
13
+
14
+ // ─── Model Type Guards ─────────────────────────────────────────────────────────
15
+
16
+ /**
17
+ * Check if a string is a valid FalModelType
18
+ *
19
+ * @param value - Value to check
20
+ * @returns Type guard indicating if the value is a FalModelType
21
+ */
22
+ export function isFalModelType(value: unknown): value is FalModelType {
23
+ const validTypes: ReadonlyArray<FalModelType> = [
24
+ "text-to-image",
25
+ "text-to-video",
26
+ "text-to-voice",
27
+ "image-to-video",
28
+ "image-to-image",
29
+ "text-to-text",
30
+ ];
31
+ return typeof value === "string" && validTypes.includes(value as FalModelType);
32
+ }
33
+
34
+ /**
35
+ * Check if a string is a valid ModelType
36
+ *
37
+ * @param value - Value to check
38
+ * @returns Type guard indicating if the value is a ModelType
39
+ */
40
+ export function isModelType(value: unknown): value is ModelType {
41
+ const validTypes: ReadonlyArray<ModelType> = [
42
+ "text-to-image",
43
+ "text-to-video",
44
+ "image-to-video",
45
+ "text-to-voice",
46
+ ];
47
+ return typeof value === "string" && validTypes.includes(value as ModelType);
48
+ }
49
+
50
+ // ─── Error Type Guards ────────────────────────────────────────────────────────
51
+
52
+ /**
53
+ * Check if error is a FalErrorType
54
+ *
55
+ * @param value - Value to check
56
+ * @returns Type guard indicating if the value is a FalErrorType
57
+ */
58
+ export function isFalErrorType(value: unknown): value is FalErrorType {
59
+ const validTypes: ReadonlyArray<FalErrorType> = [
60
+ FalErrorType.NETWORK,
61
+ FalErrorType.TIMEOUT,
62
+ FalErrorType.API_ERROR,
63
+ FalErrorType.VALIDATION,
64
+ FalErrorType.IMAGE_TOO_SMALL,
65
+ FalErrorType.CONTENT_POLICY,
66
+ FalErrorType.RATE_LIMIT,
67
+ FalErrorType.AUTHENTICATION,
68
+ FalErrorType.QUOTA_EXCEEDED,
69
+ FalErrorType.MODEL_NOT_FOUND,
70
+ FalErrorType.UNKNOWN,
71
+ ];
72
+ return typeof value === "string" && validTypes.includes(value as FalErrorType);
73
+ }
74
+
75
+ // ─── API Error Type Guards ────────────────────────────────────────────────────
76
+
77
+ /**
78
+ * Check if error is retryable based on error type
79
+ *
80
+ * @param error - Error to check
81
+ * @returns True if error is retryable
82
+ */
83
+ export function isRetryableError(error: unknown): boolean {
84
+ if (error instanceof Error) {
85
+ const message = error.message.toLowerCase();
86
+ return (
87
+ message.includes("network") ||
88
+ message.includes("timeout") ||
89
+ message.includes("timed out") ||
90
+ message.includes("econnrefused") ||
91
+ message.includes("enotfound") ||
92
+ message.includes("fetch")
93
+ );
94
+ }
95
+ return false;
96
+ }
97
+
98
+ /**
99
+ * Check if value is a local file URI
100
+ *
101
+ * @param value - Value to check
102
+ * @returns Type guard indicating if the value is a local file URI
103
+ */
104
+ export function isLocalFileUri(value: unknown): value is string {
105
+ return (
106
+ typeof value === "string" &&
107
+ (value.startsWith("file://") || value.startsWith("content://"))
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Check if value is an HTTP/HTTPS URL
113
+ *
114
+ * @param value - Value to check
115
+ * @returns Type guard indicating if the value is an HTTP/HTTPS URL
116
+ */
117
+ export function isHttpUrl(value: unknown): value is string {
118
+ return (
119
+ typeof value === "string" &&
120
+ (value.startsWith("http://") || value.startsWith("https://"))
121
+ );
122
+ }
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Shared Validation Utilities
3
+ * Consolidated validators for strings, data URIs, and business rules
4
+ *
5
+ * This file consolidates functionality from:
6
+ * - data-uri-validator.util.ts
7
+ * - string-validator.util.ts
8
+ * - validation-guards.util.ts
9
+ */
10
+
11
+ // ─── Constants ────────────────────────────────────────────────────────────────
12
+
13
+ const MIN_BASE64_IMAGE_LENGTH = 100;
14
+ const MIN_MODEL_ID_LENGTH = 3;
15
+ const MAX_PROMPT_LENGTH = 5000;
16
+ const MAX_TIMEOUT_MS = 300000; // 5 minutes
17
+ const MAX_RETRY_COUNT = 5;
18
+
19
+ const SUSPICIOUS_PATTERNS = [
20
+ /<script/i,
21
+ /javascript:/i,
22
+ /on\w+\s*=/i,
23
+ /<iframe/i,
24
+ /<embed/i,
25
+ /<object/i,
26
+ /data:(?!image\/)/i,
27
+ /vbscript:/i,
28
+ ] as const;
29
+
30
+ const MODEL_ID_PATTERN = /^[a-zA-Z0-9-_]+\/[a-zA-Z0-9-_.]+(\/[a-zA-Z0-9-_.]+)*$/;
31
+
32
+ // ─── String Validators ─────────────────────────────────────────────────────────
33
+
34
+ /**
35
+ * Check if string is empty or whitespace-only
36
+ *
37
+ * @param value - Value to check
38
+ * @returns True if the value is an empty string or contains only whitespace
39
+ */
40
+ export function isEmptyString(value: unknown): boolean {
41
+ return typeof value === "string" && value.trim().length === 0;
42
+ }
43
+
44
+ /**
45
+ * Check if value is a non-empty string
46
+ * Type guard version for better TypeScript inference
47
+ *
48
+ * @param value - Value to check
49
+ * @returns Type guard indicating if the value is a non-empty string
50
+ */
51
+ export function isNonEmptyString(value: unknown): value is string {
52
+ return typeof value === "string" && value.trim().length > 0;
53
+ }
54
+
55
+ /**
56
+ * Check if value is a string (empty or non-empty)
57
+ * Basic type guard for string validation
58
+ *
59
+ * @param value - Value to check
60
+ * @returns Type guard indicating if the value is a string
61
+ */
62
+ export function isString(value: unknown): value is string {
63
+ return typeof value === "string";
64
+ }
65
+
66
+ /**
67
+ * Check if string contains suspicious content
68
+ *
69
+ * @param value - String to check
70
+ * @returns True if suspicious patterns are found
71
+ */
72
+ function hasSuspiciousContent(value: string): boolean {
73
+ return SUSPICIOUS_PATTERNS.some((pattern) => pattern.test(value));
74
+ }
75
+
76
+ // ─── Data URI Validators ──────────────────────────────────────────────────────
77
+
78
+ /**
79
+ * Check if value is a data URI (any type)
80
+ *
81
+ * @param value - Value to check
82
+ * @returns Type guard indicating if the value is a data URI string
83
+ */
84
+ export function isDataUri(value: unknown): value is string {
85
+ return typeof value === "string" && value.startsWith("data:");
86
+ }
87
+
88
+ /**
89
+ * Check if value is an image data URI
90
+ *
91
+ * @param value - Value to check
92
+ * @returns Type guard indicating if the value is an image data URI string
93
+ */
94
+ export function isImageDataUri(value: unknown): value is string {
95
+ return typeof value === "string" && value.startsWith("data:image/");
96
+ }
97
+
98
+ /**
99
+ * Check if value is a base64-encoded data URI
100
+ *
101
+ * @param value - Value to check
102
+ * @returns Type guard indicating if the value contains base64 encoding
103
+ */
104
+ export function isBase64DataUri(value: unknown): value is string {
105
+ return isDataUri(value) && typeof value === "string" && value.includes("base64,");
106
+ }
107
+
108
+ /**
109
+ * Extract MIME type from data URI
110
+ *
111
+ * @param dataUri - Data URI string
112
+ * @returns MIME type or null if not found
113
+ */
114
+ export function extractMimeType(dataUri: string): string | null {
115
+ const match = dataUri.match(/^data:([^;,]+)/);
116
+ return match ? match[1] : null;
117
+ }
118
+
119
+ /**
120
+ * Extract base64 content from data URI
121
+ *
122
+ * @param dataUri - Data URI string
123
+ * @returns Base64 content or null if not base64-encoded
124
+ */
125
+ export function extractBase64Content(dataUri: string): string | null {
126
+ const parts = dataUri.split("base64,");
127
+ return parts.length === 2 ? parts[1] : null;
128
+ }
129
+
130
+ // ─── Business Validators ───────────────────────────────────────────────────────
131
+
132
+ /**
133
+ * Validate base64 image string
134
+ *
135
+ * @param value - Value to validate
136
+ * @returns True if value is a valid base64 image
137
+ */
138
+ export function isValidBase64Image(value: unknown): boolean {
139
+ if (typeof value !== "string") {
140
+ return false;
141
+ }
142
+
143
+ // Check data URI prefix
144
+ if (value.startsWith("data:image/")) {
145
+ const parts = value.split("base64,");
146
+ if (parts.length < 2) return false;
147
+ const base64Part = parts[1];
148
+ if (!base64Part) return false;
149
+ return base64Part.length >= MIN_BASE64_IMAGE_LENGTH;
150
+ }
151
+
152
+ // Check if it's a valid base64 string with minimum length
153
+ const base64Pattern = /^[A-Za-z0-9+/]+=*$/;
154
+ return base64Pattern.test(value) && value.length >= MIN_BASE64_IMAGE_LENGTH;
155
+ }
156
+
157
+ /**
158
+ * Validate API key format
159
+ *
160
+ * @param value - Value to validate
161
+ * @returns True if value is a valid API key
162
+ */
163
+ export function isValidApiKey(value: unknown): boolean {
164
+ return typeof value === "string" && value.length > 0;
165
+ }
166
+
167
+ /**
168
+ * Validate model ID format
169
+ * Pattern: org/model or org/model/sub1/sub2/... (multiple path segments)
170
+ * Allows dots for versions (e.g., v1.5) but prevents path traversal (..)
171
+ *
172
+ * @param value - Value to validate
173
+ * @returns True if value is a valid model ID
174
+ */
175
+ export function isValidModelId(value: unknown): boolean {
176
+ if (typeof value !== "string") {
177
+ return false;
178
+ }
179
+
180
+ // Prevent path traversal attacks
181
+ if (value.includes("..")) {
182
+ return false;
183
+ }
184
+
185
+ // Ensure it doesn't start or end with dots
186
+ if (value.startsWith(".") || value.endsWith(".")) {
187
+ return false;
188
+ }
189
+
190
+ return (
191
+ MODEL_ID_PATTERN.test(value) && value.length >= MIN_MODEL_ID_LENGTH
192
+ );
193
+ }
194
+
195
+ /**
196
+ * Validate prompt string
197
+ *
198
+ * @param value - Value to validate
199
+ * @returns True if value is a valid prompt
200
+ */
201
+ export function isValidPrompt(value: unknown): boolean {
202
+ if (!isNonEmptyString(value)) return false;
203
+ return value.length <= MAX_PROMPT_LENGTH && !hasSuspiciousContent(value);
204
+ }
205
+
206
+ /**
207
+ * Validate timeout value
208
+ *
209
+ * @param value - Value to validate
210
+ * @returns True if value is a valid timeout
211
+ */
212
+ export function isValidTimeout(value: unknown): boolean {
213
+ return (
214
+ typeof value === "number" &&
215
+ !isNaN(value) &&
216
+ isFinite(value) &&
217
+ value > 0 &&
218
+ value <= MAX_TIMEOUT_MS
219
+ );
220
+ }
221
+
222
+ /**
223
+ * Validate retry count
224
+ *
225
+ * @param value - Value to validate
226
+ * @returns True if value is a valid retry count
227
+ */
228
+ export function isValidRetryCount(value: unknown): boolean {
229
+ return (
230
+ typeof value === "number" &&
231
+ !isNaN(value) &&
232
+ isFinite(value) &&
233
+ Number.isInteger(value) &&
234
+ value >= 0 &&
235
+ value <= MAX_RETRY_COUNT
236
+ );
237
+ }
238
+
239
+ /**
240
+ * Validate URL format and protocol
241
+ * Rejects malicious URLs and unsafe protocols
242
+ *
243
+ * @param value - URL string to validate
244
+ * @returns True if URL is valid and safe
245
+ */
246
+ export function isValidAndSafeUrl(value: string): boolean {
247
+ // Allow http/https URLs
248
+ if (value.startsWith("http://") || value.startsWith("https://")) {
249
+ try {
250
+ const url = new URL(value);
251
+ // Reject URLs with @ (potential auth bypass)
252
+ if (url.href.includes("@") && url.username) {
253
+ return false;
254
+ }
255
+ // Ensure domain exists
256
+ if (!url.hostname || url.hostname.length === 0) {
257
+ return false;
258
+ }
259
+ return true;
260
+ } catch {
261
+ return false;
262
+ }
263
+ }
264
+
265
+ // Allow local file URIs
266
+ if (value.startsWith("file://") || value.startsWith("content://")) {
267
+ return true;
268
+ }
269
+
270
+ // Allow base64 image data URIs only
271
+ if (isImageDataUri(value)) {
272
+ // Check for suspicious content in data URI
273
+ const dataContent = value.substring(0, 200);
274
+ if (hasSuspiciousContent(dataContent)) {
275
+ return false;
276
+ }
277
+ return true;
278
+ }
279
+
280
+ return false;
281
+ }
@@ -1,21 +0,0 @@
1
- /**
2
- * Calculation Helper Utilities
3
- * Internal calculation functions for FAL provider
4
- */
5
-
6
- /**
7
- * Calculate elapsed time in milliseconds from a start timestamp
8
- */
9
- export function getElapsedTime(startTime: number): number {
10
- return Date.now() - startTime;
11
- }
12
-
13
- /**
14
- * Calculate actual file size from base64 string
15
- * Base64 encoding inflates size by ~33%, so actual size is ~75% of base64 length
16
- */
17
- export function getActualSizeKB(base64String: string): number {
18
- const base64SizeKB = Math.round(base64String.length / 1024);
19
- // Base64 inflates by ~33%, so actual size is ~75%
20
- return Math.round(base64SizeKB * 0.75);
21
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * Error Helper Utilities
3
- * Centralized error message extraction and formatting
4
- *
5
- * This utility eliminates the repeated pattern:
6
- * `error instanceof Error ? error.message : String(error)`
7
- * which appeared 8 times across 6 files in the codebase.
8
- */
9
-
10
- /**
11
- * Extract error message from any error type
12
- * Handles Error instances, strings, and unknown types
13
- *
14
- * @param error - The error to extract message from
15
- * @returns The error message as a string
16
- *
17
- * @example
18
- * ```typescript
19
- * try {
20
- * await riskyOperation();
21
- * } catch (error) {
22
- * console.error('Operation failed:', getErrorMessage(error));
23
- * }
24
- * ```
25
- */
26
- export function getErrorMessage(error: unknown): string {
27
- return error instanceof Error ? error.message : String(error);
28
- }
29
-
30
- /**
31
- * Extract error message with fallback
32
- * Returns fallback if error message is empty or whitespace-only
33
- *
34
- * @param error - The error to extract message from
35
- * @param fallback - Fallback message if error message is empty
36
- * @returns The error message or fallback
37
- *
38
- * @example
39
- * ```typescript
40
- * const message = getErrorMessageOr(error, 'An unknown error occurred');
41
- * ```
42
- */
43
- export function getErrorMessageOr(error: unknown, fallback: string): string {
44
- const message = getErrorMessage(error);
45
- return message && message.trim().length > 0 ? message : fallback;
46
- }
47
-
48
- /**
49
- * Create error message with context prefix
50
- * Useful for adding operation context to error messages
51
- *
52
- * @param error - The error to extract message from
53
- * @param context - Context to prepend to the error message
54
- * @returns Formatted error message with context
55
- *
56
- * @example
57
- * ```typescript
58
- * throw new Error(formatErrorMessage(error, 'Failed to upload image'));
59
- * // Output: "Failed to upload image: Network timeout"
60
- * ```
61
- */
62
- export function formatErrorMessage(error: unknown, context: string): string {
63
- return `${context}: ${getErrorMessage(error)}`;
64
- }
65
-
@@ -1,44 +0,0 @@
1
- /**
2
- * Object Helper Utilities
3
- * Object manipulation and validation helpers
4
- */
5
-
6
- /**
7
- * Build error message with context
8
- */
9
- export function buildErrorMessage(
10
- type: string,
11
- context: Record<string, unknown>
12
- ): string {
13
- const contextStr = Object.entries(context)
14
- .map(([key, value]) => `${key}=${JSON.stringify(value)}`)
15
- .join(", ");
16
- return `${type}${contextStr ? ` (${contextStr})` : ""}`;
17
- }
18
-
19
- /**
20
- * Check if value is defined (not null or undefined)
21
- */
22
- export function isDefined<T>(value: T | null | undefined): value is T {
23
- return value !== null && value !== undefined;
24
- }
25
-
26
- /**
27
- * Filter out null and undefined values from object
28
- */
29
- export function removeNullish<T extends Record<string, unknown>>(
30
- obj: T
31
- ): Partial<T> {
32
- return Object.fromEntries(
33
- Object.entries(obj).filter(([_, value]) => isDefined(value))
34
- ) as Partial<T>;
35
- }
36
-
37
- /**
38
- * Generate unique ID
39
- */
40
- export function generateUniqueId(prefix: string = ""): string {
41
- const timestamp = Date.now().toString(36);
42
- const randomStr = Math.random().toString(36).substring(2, 9);
43
- return prefix ? `${prefix}_${timestamp}${randomStr}` : `${timestamp}${randomStr}`;
44
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Timing Helper Utilities
3
- * Sleep utility for async delays
4
- */
5
-
6
- /**
7
- * Sleep for specified milliseconds
8
- */
9
- export function sleep(ms: number): Promise<void> {
10
- return new Promise((resolve) => setTimeout(resolve, ms));
11
- }