@umituz/react-native-validation 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.
package/README.md CHANGED
@@ -39,6 +39,8 @@ npm install @umituz/react-native-validation
39
39
 
40
40
  ### General
41
41
  - ✅ TypeScript type safety
42
+ - ✅ Image file validation (prevents zip, exe, etc.)
43
+ - ✅ MIME type validation
42
44
 
43
45
  ## Usage
44
46
 
@@ -141,6 +143,38 @@ const isDangerous = containsDangerousChars('<script>alert("xss")</script>');
141
143
  const isValidLength = isWithinLengthLimit('text', SECURITY_LIMITS.NAME_MAX_LENGTH);
142
144
  ```
143
145
 
146
+ ### Image Validation Example
147
+
148
+ ```typescript
149
+ import {
150
+ validateImageUri,
151
+ getImageMimeType,
152
+ validateImageExtension,
153
+ IMAGE_MIME_TYPES,
154
+ } from '@umituz/react-native-validation';
155
+
156
+ // Validate image URI (supports file://, http://, https://, and data: URLs)
157
+ const result = validateImageUri('file:///path/to/image.jpg');
158
+ if (!result.isValid) {
159
+ console.error(result.error);
160
+ }
161
+
162
+ // Get MIME type from URI
163
+ const mimeType = getImageMimeType('file:///path/to/image.png');
164
+ // Result: 'image/png'
165
+
166
+ // Validate file extension
167
+ const extensionResult = validateImageExtension('image.jpg');
168
+ if (!extensionResult.isValid) {
169
+ console.error(extensionResult.error);
170
+ }
171
+
172
+ // Use MIME type constants
173
+ if (mimeType === IMAGE_MIME_TYPES.PNG) {
174
+ console.log('PNG image');
175
+ }
176
+ ```
177
+
144
178
  ## API Reference
145
179
 
146
180
  ### Core Validators
@@ -168,6 +202,23 @@ const isValidLength = isWithinLengthLimit('text', SECURITY_LIMITS.NAME_MAX_LENGT
168
202
  - `validateDateOfBirth(date: Date): ValidationResult`
169
203
  - `validateAge(age: number): ValidationResult` (13-120 years)
170
204
 
205
+ ### Image Validators
206
+
207
+ - `validateImageUri(uri: string, fieldName?: string): ValidationResult` - Validates image URI (supports file://, http://, https://, and data: URLs)
208
+ - `validateImageMimeType(mimeType: string, fieldName?: string): ValidationResult` - Validates MIME type is supported image type
209
+ - `validateImageExtension(uri: string, fieldName?: string): ValidationResult` - Validates file extension is supported image type
210
+ - `validateImageDataUrl(dataUrl: string, fieldName?: string): ValidationResult` - Validates data URL is image type
211
+ - `getImageMimeType(uri: string): string | null` - Get MIME type from URI (supports all URI types)
212
+
213
+ ### MIME Type Utilities
214
+
215
+ - `getMimeTypeFromExtension(uri: string): string | null` - Get MIME type from file extension
216
+ - `getMimeTypeFromDataUrl(dataUrl: string): string | null` - Get MIME type from data URL
217
+ - `IMAGE_MIME_TYPES` - Supported image MIME types constants
218
+ - `SUPPORTED_IMAGE_MIME_TYPES` - Array of supported image MIME types
219
+ - `EXTENSION_TO_MIME_TYPE` - File extension to MIME type mapping
220
+ - `MIME_TYPE_TO_EXTENSION` - MIME type to file extension mapping
221
+
171
222
  ### Batch Validation
172
223
 
173
224
  - `batchValidate(validations: Array<{ field: string; validator: () => ValidationResult }>): { isValid: boolean; errors: Record<string, string> }`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-validation",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Comprehensive validation and sanitization utilities for React Native forms",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -40,3 +40,22 @@ export {
40
40
  isWithinLengthLimit,
41
41
  } from './infrastructure/utils/sanitization';
42
42
 
43
+ // Infrastructure Layer - MIME Type Validation
44
+ export {
45
+ IMAGE_MIME_TYPES,
46
+ SUPPORTED_IMAGE_MIME_TYPES,
47
+ EXTENSION_TO_MIME_TYPE,
48
+ MIME_TYPE_TO_EXTENSION,
49
+ } from './infrastructure/utils/mime-types.constants';
50
+
51
+ export {
52
+ getMimeTypeFromExtension,
53
+ getMimeTypeFromDataUrl,
54
+ validateImageMimeType,
55
+ validateImageExtension,
56
+ validateImageDataUrl,
57
+ } from './infrastructure/utils/mime-type-validator';
58
+
59
+ // Infrastructure Layer - Image Validation
60
+ export { validateImageUri, getImageMimeType } from './infrastructure/utils/image-validator';
61
+
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Image Validator
3
+ * Single Responsibility: Validate image files and URIs
4
+ */
5
+
6
+ import type { ValidationResult } from '../../domain/entities/ValidationResult';
7
+ import {
8
+ validateImageExtension,
9
+ validateImageDataUrl,
10
+ getMimeTypeFromExtension,
11
+ getMimeTypeFromDataUrl,
12
+ } from './mime-type-validator';
13
+
14
+ /**
15
+ * Check if URI is a local file path
16
+ */
17
+ function isLocalFileUrl(uri: string): boolean {
18
+ return uri.startsWith('file://');
19
+ }
20
+
21
+ /**
22
+ * Check if URI is a public URL
23
+ */
24
+ function isPublicUrl(uri: string): boolean {
25
+ return uri.startsWith('http://') || uri.startsWith('https://');
26
+ }
27
+
28
+ /**
29
+ * Check if URI is a data URL
30
+ */
31
+ function isDataUrl(uri: string): boolean {
32
+ return uri.startsWith('data:');
33
+ }
34
+
35
+ /**
36
+ * Validate image URI (supports file://, http://, https://, and data: URLs)
37
+ */
38
+ export function validateImageUri(
39
+ uri: string,
40
+ fieldName: string = 'Image'
41
+ ): ValidationResult {
42
+ if (!uri || uri.trim() === '') {
43
+ return { isValid: false, error: `${fieldName} is required` };
44
+ }
45
+
46
+ // Validate public URLs (assume they're images if they have image extension)
47
+ if (isPublicUrl(uri)) {
48
+ return validateImageExtension(uri, fieldName);
49
+ }
50
+
51
+ // Validate data URLs
52
+ if (isDataUrl(uri)) {
53
+ return validateImageDataUrl(uri, fieldName);
54
+ }
55
+
56
+ // Validate local file URLs
57
+ if (isLocalFileUrl(uri)) {
58
+ return validateImageExtension(uri, fieldName);
59
+ }
60
+
61
+ // Unknown format
62
+ return {
63
+ isValid: false,
64
+ error: `${fieldName} must be a valid image URL or file path`,
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Get MIME type from URI (supports all URI types)
70
+ */
71
+ export function getImageMimeType(uri: string): string | null {
72
+ if (isDataUrl(uri)) {
73
+ return getMimeTypeFromDataUrl(uri);
74
+ }
75
+
76
+ return getMimeTypeFromExtension(uri);
77
+ }
78
+
@@ -0,0 +1,94 @@
1
+ /**
2
+ * MIME Type Validator
3
+ * Single Responsibility: Validate MIME types
4
+ */
5
+
6
+ import type { ValidationResult } from '../../domain/entities/ValidationResult';
7
+ import {
8
+ SUPPORTED_IMAGE_MIME_TYPES,
9
+ EXTENSION_TO_MIME_TYPE,
10
+ } from './mime-types.constants';
11
+
12
+ /**
13
+ * Get MIME type from file extension
14
+ */
15
+ export function getMimeTypeFromExtension(uri: string): string | null {
16
+ const extension = uri.toLowerCase().split('.').pop();
17
+ if (!extension) {
18
+ return null;
19
+ }
20
+ return EXTENSION_TO_MIME_TYPE[extension] || null;
21
+ }
22
+
23
+ /**
24
+ * Get MIME type from data URL
25
+ */
26
+ export function getMimeTypeFromDataUrl(dataUrl: string): string | null {
27
+ const match = dataUrl.match(/^data:([^;]+);/);
28
+ return match ? match[1] : null;
29
+ }
30
+
31
+ /**
32
+ * Validate MIME type is supported image type
33
+ */
34
+ export function validateImageMimeType(
35
+ mimeType: string,
36
+ fieldName: string = 'File'
37
+ ): ValidationResult {
38
+ if (!mimeType) {
39
+ return { isValid: false, error: `${fieldName} MIME type is required` };
40
+ }
41
+
42
+ if (!SUPPORTED_IMAGE_MIME_TYPES.includes(mimeType as any)) {
43
+ return {
44
+ isValid: false,
45
+ error: `${fieldName} must be an image (JPEG, PNG, WEBP, or GIF)`,
46
+ };
47
+ }
48
+
49
+ return { isValid: true };
50
+ }
51
+
52
+ /**
53
+ * Validate file extension is supported image type
54
+ */
55
+ export function validateImageExtension(
56
+ uri: string,
57
+ fieldName: string = 'File'
58
+ ): ValidationResult {
59
+ const mimeType = getMimeTypeFromExtension(uri);
60
+ if (!mimeType) {
61
+ return {
62
+ isValid: false,
63
+ error: `${fieldName} must have a valid image extension (jpg, jpeg, png, webp, gif)`,
64
+ };
65
+ }
66
+
67
+ return validateImageMimeType(mimeType, fieldName);
68
+ }
69
+
70
+ /**
71
+ * Validate data URL is image type
72
+ */
73
+ export function validateImageDataUrl(
74
+ dataUrl: string,
75
+ fieldName: string = 'File'
76
+ ): ValidationResult {
77
+ if (!dataUrl || !dataUrl.startsWith('data:')) {
78
+ return {
79
+ isValid: false,
80
+ error: `${fieldName} must be a valid data URL`,
81
+ };
82
+ }
83
+
84
+ const mimeType = getMimeTypeFromDataUrl(dataUrl);
85
+ if (!mimeType) {
86
+ return {
87
+ isValid: false,
88
+ error: `${fieldName} must have a valid MIME type`,
89
+ };
90
+ }
91
+
92
+ return validateImageMimeType(mimeType, fieldName);
93
+ }
94
+
@@ -0,0 +1,42 @@
1
+ /**
2
+ * MIME Type Constants
3
+ * Single Responsibility: Define supported MIME types for validation
4
+ */
5
+
6
+ /**
7
+ * Supported image MIME types
8
+ */
9
+ export const IMAGE_MIME_TYPES = {
10
+ JPEG: 'image/jpeg',
11
+ JPG: 'image/jpeg',
12
+ PNG: 'image/png',
13
+ WEBP: 'image/webp',
14
+ GIF: 'image/gif',
15
+ } as const;
16
+
17
+ /**
18
+ * All supported image MIME types as array
19
+ */
20
+ export const SUPPORTED_IMAGE_MIME_TYPES = Object.values(IMAGE_MIME_TYPES);
21
+
22
+ /**
23
+ * File extension to MIME type mapping
24
+ */
25
+ export const EXTENSION_TO_MIME_TYPE: Record<string, string> = {
26
+ jpg: IMAGE_MIME_TYPES.JPEG,
27
+ jpeg: IMAGE_MIME_TYPES.JPEG,
28
+ png: IMAGE_MIME_TYPES.PNG,
29
+ webp: IMAGE_MIME_TYPES.WEBP,
30
+ gif: IMAGE_MIME_TYPES.GIF,
31
+ };
32
+
33
+ /**
34
+ * MIME type to file extension mapping
35
+ */
36
+ export const MIME_TYPE_TO_EXTENSION: Record<string, string> = {
37
+ [IMAGE_MIME_TYPES.JPEG]: 'jpg',
38
+ [IMAGE_MIME_TYPES.PNG]: 'png',
39
+ [IMAGE_MIME_TYPES.WEBP]: 'webp',
40
+ [IMAGE_MIME_TYPES.GIF]: 'gif',
41
+ };
42
+