@umituz/react-native-ai-generation-content 1.90.9 → 1.90.11
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 +1 -1
- package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +3 -3
- package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +3 -3
- package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +1 -1
- package/src/domains/creations/domain/constants/creation-fields.constants.ts +1 -1
- package/src/domains/creations/presentation/hooks/useCreationPersistence.ts +2 -1
- package/src/domains/image-to-video/presentation/hooks/useImageToVideoFeature.ts +2 -2
- package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +2 -2
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoFeature.ts +2 -2
- package/src/infrastructure/validation/advanced-validator.ts +21 -16
- package/src/infrastructure/validation/base-validator.ts +17 -75
- package/src/shared-kernel/infrastructure/validation/index.ts +3 -43
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.90.
|
|
3
|
+
"version": "1.90.11",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts
CHANGED
|
@@ -39,10 +39,10 @@ class ImageModerator extends BaseModerator {
|
|
|
39
39
|
// Use shared URL validation
|
|
40
40
|
const urlValidation = validateUrl(uri);
|
|
41
41
|
if (!urlValidation.isValid) {
|
|
42
|
-
if (urlValidation.errors
|
|
42
|
+
if ('required' in urlValidation.errors) {
|
|
43
43
|
return this.createViolation("empty-uri", "Image Validation", "empty URI");
|
|
44
44
|
}
|
|
45
|
-
if (urlValidation.errors
|
|
45
|
+
if ('pattern' in urlValidation.errors) {
|
|
46
46
|
return this.createViolation(
|
|
47
47
|
"invalid-protocol",
|
|
48
48
|
"Image Validation",
|
|
@@ -57,7 +57,7 @@ class ImageModerator extends BaseModerator {
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
if (!lengthValidation.isValid) {
|
|
60
|
-
if (lengthValidation.errors
|
|
60
|
+
if ('maxLength' in lengthValidation.errors) {
|
|
61
61
|
return this.createViolation(
|
|
62
62
|
"uri-too-long",
|
|
63
63
|
"Image Validation",
|
|
@@ -63,7 +63,7 @@ class TextModerator extends BaseModerator {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
if (!stringValidation.isValid) {
|
|
66
|
-
if (stringValidation.errors
|
|
66
|
+
if ('maxLength' in stringValidation.errors) {
|
|
67
67
|
return this.createViolation("too-long", "Validation", "length exceeded");
|
|
68
68
|
}
|
|
69
69
|
return this.createViolation("empty-content", "Validation", "empty");
|
package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts
CHANGED
|
@@ -39,10 +39,10 @@ class VideoModerator extends BaseModerator {
|
|
|
39
39
|
// Use shared URL validation
|
|
40
40
|
const urlValidation = validateUrl(uri);
|
|
41
41
|
if (!urlValidation.isValid) {
|
|
42
|
-
if (urlValidation.errors
|
|
42
|
+
if ('required' in urlValidation.errors) {
|
|
43
43
|
return this.createViolation("empty-uri", "Video Validation", "empty URI");
|
|
44
44
|
}
|
|
45
|
-
if (urlValidation.errors
|
|
45
|
+
if ('pattern' in urlValidation.errors) {
|
|
46
46
|
return this.createViolation(
|
|
47
47
|
"invalid-protocol",
|
|
48
48
|
"Video Validation",
|
|
@@ -57,7 +57,7 @@ class VideoModerator extends BaseModerator {
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
if (!lengthValidation.isValid) {
|
|
60
|
-
if (lengthValidation.errors
|
|
60
|
+
if ('maxLength' in lengthValidation.errors) {
|
|
61
61
|
return this.createViolation(
|
|
62
62
|
"uri-too-long",
|
|
63
63
|
"Video Validation",
|
|
@@ -53,7 +53,8 @@ export function useCreationPersistence(
|
|
|
53
53
|
|
|
54
54
|
const validation = runAllValidations(result.imageUrl, result.videoUrl);
|
|
55
55
|
if (!validation.isValid) {
|
|
56
|
-
|
|
56
|
+
const firstError = Object.values(validation.errors)[0];
|
|
57
|
+
await markCreationAsFailed(repository, userId, result.creationId, firstError || "Validation failed");
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -41,14 +41,14 @@ export function useImageToVideoFeature(props: UseImageToVideoFeatureProps): UseI
|
|
|
41
41
|
const orchestrator = useGenerationOrchestrator(strategy, {
|
|
42
42
|
userId,
|
|
43
43
|
alertMessages: DEFAULT_ALERT_MESSAGES,
|
|
44
|
-
onSuccess: (result: unknown) => {
|
|
44
|
+
onSuccess: async (result: unknown) => {
|
|
45
45
|
const typedResult = result as { success: boolean; videoUrl?: string; thumbnailUrl?: string };
|
|
46
46
|
if (typedResult.success && typedResult.videoUrl) {
|
|
47
47
|
config.onProcessingComplete?.(typedResult);
|
|
48
48
|
callbacks?.onGenerate?.(typedResult);
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
|
-
onError: (err) => {
|
|
51
|
+
onError: async (err) => {
|
|
52
52
|
config.onError?.(err.message);
|
|
53
53
|
callbacks?.onError?.(err.message);
|
|
54
54
|
},
|
|
@@ -72,7 +72,7 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
|
|
|
72
72
|
const { generate, isGenerating, error } = useGenerationOrchestrator(strategy, {
|
|
73
73
|
userId: userId ?? undefined,
|
|
74
74
|
alertMessages: DEFAULT_ALERT_MESSAGES,
|
|
75
|
-
onSuccess: (result) => {
|
|
75
|
+
onSuccess: async (result) => {
|
|
76
76
|
const imageUrls = result as string[];
|
|
77
77
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
78
78
|
console.log("[TextToImage] Success! Generated", imageUrls.length, "image(s)");
|
|
@@ -80,7 +80,7 @@ export function useGeneration(options: UseGenerationOptions): UseGenerationRetur
|
|
|
80
80
|
callbacks.onSuccess?.(imageUrls);
|
|
81
81
|
onPromptCleared?.();
|
|
82
82
|
},
|
|
83
|
-
onError: (err) => {
|
|
83
|
+
onError: async (err) => {
|
|
84
84
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
85
85
|
console.log("[TextToImage] Error:", err.message);
|
|
86
86
|
}
|
|
@@ -71,8 +71,8 @@ export function useTextToVideoFeature(props: UseTextToVideoFeatureProps): UseTex
|
|
|
71
71
|
const orchestrator = useGenerationOrchestrator(strategy, {
|
|
72
72
|
userId,
|
|
73
73
|
alertMessages: DEFAULT_ALERT_MESSAGES,
|
|
74
|
-
onSuccess: (result) => callbacks.onGenerate?.(result as TextToVideoResult),
|
|
75
|
-
onError: (err) => callbacks.onError?.(err.message),
|
|
74
|
+
onSuccess: async (result) => callbacks.onGenerate?.(result as TextToVideoResult),
|
|
75
|
+
onError: async (err) => callbacks.onError?.(err.message),
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
const setPrompt = useCallback((prompt: string) => {
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* Complex validators for objects, arrays, and combined validations
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ValidationResult } from "
|
|
7
|
-
import { validateString } from "
|
|
8
|
-
import type { StringValidationOptions } from "./base-validator";
|
|
6
|
+
import type { ValidationResult, StringValidationOptions } from "../../shared-kernel/infrastructure/validation";
|
|
7
|
+
import { validateString } from "../../shared-kernel/infrastructure/validation";
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Validates object structure
|
|
@@ -14,19 +13,19 @@ export function validateObject(
|
|
|
14
13
|
input: unknown,
|
|
15
14
|
requiredFields: readonly string[] = []
|
|
16
15
|
): ValidationResult {
|
|
17
|
-
const errors: string
|
|
16
|
+
const errors: Record<string, string> = {};
|
|
18
17
|
|
|
19
18
|
if (typeof input !== "object" || input === null) {
|
|
20
|
-
return { isValid: false, errors:
|
|
19
|
+
return { isValid: false, errors: { input: "Input must be an object" } };
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
for (const field of requiredFields) {
|
|
24
23
|
if (!(field in input)) {
|
|
25
|
-
errors
|
|
24
|
+
errors[field] = `Missing required field: ${field}`;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
return { isValid: errors.length === 0, errors };
|
|
28
|
+
return { isValid: Object.keys(errors).length === 0, errors };
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/**
|
|
@@ -40,18 +39,18 @@ export function validateArray(
|
|
|
40
39
|
readonly itemType?: "string" | "number" | "object";
|
|
41
40
|
} = {}
|
|
42
41
|
): ValidationResult {
|
|
43
|
-
const errors: string
|
|
42
|
+
const errors: Record<string, string> = {};
|
|
44
43
|
|
|
45
44
|
if (!Array.isArray(input)) {
|
|
46
|
-
return { isValid: false, errors:
|
|
45
|
+
return { isValid: false, errors: { input: "Input must be an array" } };
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
if (options.minLength !== undefined && input.length < options.minLength) {
|
|
50
|
-
errors.
|
|
49
|
+
errors.minLength = `Array must have at least ${options.minLength} items`;
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
if (options.maxLength !== undefined && input.length > options.maxLength) {
|
|
54
|
-
errors.
|
|
53
|
+
errors.maxLength = `Array must have at most ${options.maxLength} items`;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
if (options.itemType) {
|
|
@@ -65,22 +64,28 @@ export function validateArray(
|
|
|
65
64
|
: typeof item === "object" && item !== null;
|
|
66
65
|
|
|
67
66
|
if (!isValidType) {
|
|
68
|
-
errors
|
|
67
|
+
errors[`item_${i}`] = `Item at index ${i} is not a ${options.itemType}`;
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
return { isValid: errors.length === 0, errors };
|
|
72
|
+
return { isValid: Object.keys(errors).length === 0, errors };
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
/**
|
|
77
76
|
* Combines multiple validation results
|
|
78
77
|
*/
|
|
79
78
|
export function combineValidationResults(
|
|
80
|
-
results:
|
|
79
|
+
...results: ValidationResult[]
|
|
81
80
|
): ValidationResult {
|
|
82
|
-
const allErrors = results.
|
|
83
|
-
|
|
81
|
+
const allErrors = results.reduce((acc, result) => {
|
|
82
|
+
return { ...acc, ...result.errors };
|
|
83
|
+
}, {} as Record<string, string>);
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
isValid: Object.keys(allErrors).length === 0,
|
|
87
|
+
errors: allErrors,
|
|
88
|
+
};
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
/**
|
|
@@ -3,89 +3,31 @@
|
|
|
3
3
|
* Core validation functions for strings, numbers, URLs, emails, and base64
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ValidationResult, StringValidationOptions,
|
|
6
|
+
import type { ValidationResult, StringValidationOptions, NumberValidationOptions } from "../../shared-kernel/infrastructure/validation";
|
|
7
|
+
import { validateString, validateNumber } from "../../shared-kernel/infrastructure/validation";
|
|
7
8
|
|
|
8
9
|
// Re-export types for convenience
|
|
9
|
-
export type { ValidationResult, StringValidationOptions,
|
|
10
|
+
export type { ValidationResult, StringValidationOptions, NumberValidationOptions } from "../../shared-kernel/infrastructure/validation";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
export function validateString(
|
|
15
|
-
input: unknown,
|
|
16
|
-
options: StringValidationOptions = {}
|
|
17
|
-
): ValidationResult {
|
|
18
|
-
const errors: string[] = [];
|
|
19
|
-
|
|
20
|
-
if (typeof input !== "string") {
|
|
21
|
-
return { isValid: false, errors: ["Input must be a string"] };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const value = options.trim !== false ? input.trim() : input;
|
|
25
|
-
|
|
26
|
-
if (options.minLength !== undefined && value.length < options.minLength) {
|
|
27
|
-
errors.push(`Input must be at least ${options.minLength} characters`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (options.maxLength !== undefined && value.length > options.maxLength) {
|
|
31
|
-
errors.push(`Input must be at most ${options.maxLength} characters`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (options.pattern && !options.pattern.test(value)) {
|
|
35
|
-
errors.push("Input format is invalid");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (options.allowedCharacters && !options.allowedCharacters.test(value)) {
|
|
39
|
-
errors.push("Input contains invalid characters");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return { isValid: errors.length === 0, errors };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Validates a numeric input
|
|
47
|
-
*/
|
|
48
|
-
export function validateNumber(
|
|
49
|
-
input: unknown,
|
|
50
|
-
options: NumericValidationOptions = {}
|
|
51
|
-
): ValidationResult {
|
|
52
|
-
const errors: string[] = [];
|
|
53
|
-
|
|
54
|
-
if (typeof input !== "number" || isNaN(input)) {
|
|
55
|
-
return { isValid: false, errors: ["Input must be a number"] };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (options.integer && !Number.isInteger(input)) {
|
|
59
|
-
errors.push("Input must be an integer");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (options.min !== undefined && input < options.min) {
|
|
63
|
-
errors.push(`Input must be at least ${options.min}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (options.max !== undefined && input > options.max) {
|
|
67
|
-
errors.push(`Input must be at most ${options.max}`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return { isValid: errors.length === 0, errors };
|
|
71
|
-
}
|
|
12
|
+
// Re-export validation functions for convenience
|
|
13
|
+
export { validateString, validateNumber };
|
|
72
14
|
|
|
73
15
|
/**
|
|
74
16
|
* Validates URL format
|
|
75
17
|
*/
|
|
76
18
|
export function validateURL(input: unknown): ValidationResult {
|
|
77
19
|
if (typeof input !== "string") {
|
|
78
|
-
return { isValid: false, errors:
|
|
20
|
+
return { isValid: false, errors: { type: "URL must be a string" } };
|
|
79
21
|
}
|
|
80
22
|
|
|
81
23
|
try {
|
|
82
24
|
const url = new URL(input) as URL & { protocol: string };
|
|
83
25
|
if (!["http:", "https:"].includes(url.protocol)) {
|
|
84
|
-
return { isValid: false, errors:
|
|
26
|
+
return { isValid: false, errors: { protocol: "Only HTTP and HTTPS protocols are allowed" } };
|
|
85
27
|
}
|
|
86
|
-
return { isValid: true, errors:
|
|
28
|
+
return { isValid: true, errors: {} };
|
|
87
29
|
} catch {
|
|
88
|
-
return { isValid: false, errors:
|
|
30
|
+
return { isValid: false, errors: { format: "Invalid URL format" } };
|
|
89
31
|
}
|
|
90
32
|
}
|
|
91
33
|
|
|
@@ -94,15 +36,15 @@ export function validateURL(input: unknown): ValidationResult {
|
|
|
94
36
|
*/
|
|
95
37
|
export function validateEmail(input: unknown): ValidationResult {
|
|
96
38
|
if (typeof input !== "string") {
|
|
97
|
-
return { isValid: false, errors:
|
|
39
|
+
return { isValid: false, errors: { type: "Email must be a string" } };
|
|
98
40
|
}
|
|
99
41
|
|
|
100
42
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
101
43
|
if (!emailRegex.test(input)) {
|
|
102
|
-
return { isValid: false, errors:
|
|
44
|
+
return { isValid: false, errors: { format: "Invalid email format" } };
|
|
103
45
|
}
|
|
104
46
|
|
|
105
|
-
return { isValid: true, errors:
|
|
47
|
+
return { isValid: true, errors: {} };
|
|
106
48
|
}
|
|
107
49
|
|
|
108
50
|
/**
|
|
@@ -110,21 +52,21 @@ export function validateEmail(input: unknown): ValidationResult {
|
|
|
110
52
|
*/
|
|
111
53
|
export function validateBase64(input: unknown): ValidationResult {
|
|
112
54
|
if (typeof input !== "string") {
|
|
113
|
-
return { isValid: false, errors:
|
|
55
|
+
return { isValid: false, errors: { type: "Input must be a string" } };
|
|
114
56
|
}
|
|
115
57
|
|
|
116
58
|
if (input.length === 0) {
|
|
117
|
-
return { isValid: false, errors:
|
|
59
|
+
return { isValid: false, errors: { length: "Base64 string cannot be empty" } };
|
|
118
60
|
}
|
|
119
61
|
|
|
120
62
|
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
121
63
|
if (!base64Regex.test(input)) {
|
|
122
|
-
return { isValid: false, errors:
|
|
64
|
+
return { isValid: false, errors: { format: "Invalid base64 format" } };
|
|
123
65
|
}
|
|
124
66
|
|
|
125
67
|
if (input.length % 4 !== 0) {
|
|
126
|
-
return { isValid: false, errors:
|
|
68
|
+
return { isValid: false, errors: { length: "Base64 string length must be a multiple of 4" } };
|
|
127
69
|
}
|
|
128
70
|
|
|
129
|
-
return { isValid: true, errors:
|
|
71
|
+
return { isValid: true, errors: {} };
|
|
130
72
|
}
|
|
@@ -2,18 +2,9 @@
|
|
|
2
2
|
* Shared Validation Utilities
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
NumericValidationOptions,
|
|
9
|
-
} from "../../../infrastructure/validation/base-validator.types";
|
|
10
|
-
|
|
11
|
-
// Re-export types
|
|
12
|
-
export type {
|
|
13
|
-
ValidationResult,
|
|
14
|
-
StringValidationOptions,
|
|
15
|
-
NumericValidationOptions,
|
|
16
|
-
};
|
|
5
|
+
// Export all from common-validators
|
|
6
|
+
export * from "./common-validators";
|
|
7
|
+
export * from "./common-validators.types";
|
|
17
8
|
|
|
18
9
|
// Export functions from advanced-validator
|
|
19
10
|
export { combineValidationResults } from "../../../infrastructure/validation/advanced-validator";
|
|
@@ -22,37 +13,6 @@ export { combineValidationResults } from "../../../infrastructure/validation/adv
|
|
|
22
13
|
export { handleError } from "./error-handler";
|
|
23
14
|
export { ErrorType } from "./error-handler.types";
|
|
24
15
|
|
|
25
|
-
/**
|
|
26
|
-
* Validate a string is not empty
|
|
27
|
-
*/
|
|
28
|
-
export function validateString(value: string): ValidationResult {
|
|
29
|
-
if (typeof value !== 'string') {
|
|
30
|
-
return { isValid: false, errors: ['Value must be a string'] };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (value.trim().length === 0) {
|
|
34
|
-
return { isValid: false, errors: ['String cannot be empty'] };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return { isValid: true, errors: [] };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Validate URL format
|
|
42
|
-
*/
|
|
43
|
-
export function validateUrl(url: string): ValidationResult {
|
|
44
|
-
if (typeof url !== 'string') {
|
|
45
|
-
return { isValid: false, errors: ['URL must be a string'] };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
new URL(url);
|
|
50
|
-
return { isValid: true, errors: [] };
|
|
51
|
-
} catch {
|
|
52
|
-
return { isValid: false, errors: ['Invalid URL format'] };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
16
|
/**
|
|
57
17
|
* Validate required fields in an object
|
|
58
18
|
*/
|