@umituz/react-native-ai-generation-content 1.90.1 → 1.90.3
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 -4
- package/src/domain/interfaces/app-services-auth.interface.ts +27 -0
- package/src/domain/interfaces/app-services-composite.interface.ts +29 -0
- package/src/domain/interfaces/app-services-optional.interface.ts +42 -0
- package/src/domain/interfaces/app-services.interface.ts +0 -79
- package/src/domains/background/infrastructure/services/job-poller-index.ts +7 -0
- package/src/domains/background/infrastructure/services/job-poller-utils.ts +130 -0
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +1 -1
- package/src/domains/background/presentation/hooks/use-background-generation.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts +1 -1
- package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/text.moderator.ts +15 -4
- package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts +34 -8
- package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts +19 -8
- package/src/domains/creations/domain/types/creation-categories.constants.ts +57 -0
- package/src/domains/creations/domain/types/creation-categories.helpers.ts +67 -0
- package/src/domains/creations/domain/types/creation-categories.ts +5 -111
- package/src/domains/creations/presentation/hooks/creation-validators.ts +31 -29
- package/src/domains/creations/presentation/hooks/job-poller-index.ts +10 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.filters.ts +34 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.logger.ts +76 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.stale-handlers.ts +52 -0
- package/src/domains/creations/presentation/hooks/job-poller-utils.ts +8 -0
- package/src/domains/creations/presentation/screens/CreationsGalleryScreen.tsx +1 -1
- package/src/domains/creations/presentation-exports.ts +2 -2
- package/src/domains/face-detection/domain/entities/FaceDetection.ts +4 -3
- package/src/domains/face-detection/presentation/hooks/useFaceDetection.ts +24 -21
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-preparation.ts +58 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-prompt.ts +69 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple-resolution.ts +77 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-couple.ts +54 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder-scenario.ts +113 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/builder.ts +7 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/index.ts +20 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/types.ts +44 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-end-logger.ts +18 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-start-logger.ts +57 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/builder-step-logger.ts +106 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/index.ts +8 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils/types.ts +49 -0
- package/src/domains/generation/infrastructure/couple-generation-builder/utils.ts +8 -0
- package/src/domains/generation/infrastructure/flow/flow-store-actions.ts +105 -0
- package/src/domains/generation/infrastructure/flow/flow-store-initial-state.ts +26 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +4 -116
- package/src/domains/generation/presentation/useAIGeneration.hook.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation-strategy-index.ts +7 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.ts +2 -12
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.types.ts +11 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.executor.utils.ts +12 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-generation.strategy.ts +1 -220
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-builder.ts +66 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-extraction.ts +88 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-prompt-builder.ts +75 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-input-style-enhancements.ts +35 -0
- package/src/domains/generation/wizard/infrastructure/strategies/image-strategy-factory.ts +42 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor-index.ts +11 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-executor.ts +76 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-input-builder.ts +46 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-result-types.ts +17 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation-submission.ts +62 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.audio-extractor.ts +27 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.executor.ts +2 -175
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.input-builder.ts +90 -0
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.strategy.ts +3 -108
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.types.ts +0 -129
- package/src/domains/generation/wizard/infrastructure/strategies/video-generation.validation.ts +136 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/index.ts +39 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/types.ts +37 -0
- package/src/domains/generation/wizard/presentation/hooks/photo-upload/usePhotoUploadStateLogic.ts +142 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-utils.ts +103 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.handlers.ts +97 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.saver.ts +54 -0
- package/src/domains/generation/wizard/presentation/hooks/usePhotoBlockingGeneration.ts +22 -87
- package/src/domains/generation/wizard/presentation/hooks/usePhotoUploadState.ts +8 -177
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +1 -295
- package/src/domains/generation/wizard/presentation/hooks/useWizardGeneration.ts +1 -1
- package/src/domains/generation/wizard/presentation/hooks/video-queue/index.ts +82 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationCallbacks.ts +120 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationPolling.ts +76 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationRefs.ts +65 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue/useVideoQueueGenerationStart.ts +123 -0
- package/src/domains/generation/wizard/presentation/hooks/video-queue-index.ts +9 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +11 -4
- package/src/domains/text-to-image/domain/types/text-to-image.types.ts +44 -22
- package/src/domains/text-to-video/domain/types/request.types.ts +33 -9
- package/src/domains/text-to-video/domain/types/state.types.ts +29 -9
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.handlers.ts +44 -0
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.ts +5 -51
- package/src/domains/text-to-video/presentation/hooks/useTextToVideoForm.types.ts +33 -0
- package/src/infrastructure/services/generation-orchestrator.service.ts +2 -2
- package/src/infrastructure/utils/couple-input-context.ts +13 -0
- package/src/infrastructure/utils/couple-input-index.ts +8 -0
- package/src/infrastructure/utils/couple-input-refiner.ts +101 -0
- package/src/infrastructure/utils/couple-input-resolver.ts +71 -0
- package/src/infrastructure/utils/couple-input-types.ts +14 -0
- package/src/infrastructure/utils/couple-input.util.ts +3 -176
- package/src/infrastructure/utils/photo-generation/photo-preparation.util.ts +1 -1
- package/src/infrastructure/validation/base-validator.ts +1 -27
- package/src/infrastructure/validation/base-validator.types.ts +32 -0
- package/src/presentation/hooks/generation/index.ts +1 -1
- package/src/presentation/hooks/generation/orchestrator-abort-logs.ts +48 -0
- package/src/presentation/hooks/generation/orchestrator-execution-logs.ts +67 -0
- package/src/presentation/hooks/generation/orchestrator-index.ts +14 -0
- package/src/presentation/hooks/generation/orchestrator-start-logs.ts +65 -0
- package/src/presentation/hooks/generation/orchestrator-state-utils.ts +17 -0
- package/src/presentation/hooks/generation/orchestrator-types.ts +55 -0
- package/src/presentation/hooks/generation/orchestrator-utils-index.ts +29 -0
- package/src/presentation/hooks/generation/orchestrator-utils.ts +25 -0
- package/src/presentation/hooks/generation/useDualImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useImageGeneration.ts +1 -1
- package/src/presentation/hooks/generation/useVideoGeneration.ts +1 -1
- package/src/shared/hooks/factories/generation-hook-index.ts +12 -0
- package/src/shared/hooks/factories/generation-hook-types.ts +47 -0
- package/src/shared/hooks/factories/generation-hook-utils.ts +94 -0
- package/src/shared/hooks/factories/index.ts +1 -1
- package/src/shared/index.ts +1 -1
- package/src/shared/utils/calculations/aspect-ratio-calculations.ts +30 -0
- package/src/shared/utils/calculations/base64-calculations.ts +26 -0
- package/src/shared/utils/calculations/confidence-calculations.ts +21 -0
- package/src/shared/utils/calculations/cost-calculations-index.ts +43 -0
- package/src/shared/utils/calculations/cost-calculations.ts +25 -0
- package/src/shared/utils/calculations/credit-calculations.ts +37 -0
- package/src/shared/utils/calculations/index.ts +46 -0
- package/src/shared/utils/calculations/math-utilities.ts +32 -0
- package/src/shared/utils/calculations/memory-calculations.ts +33 -0
- package/src/shared/utils/calculations/pagination-calculations.ts +38 -0
- package/src/shared/utils/calculations/percentage-calculations.ts +33 -0
- package/src/shared/utils/calculations/time-calculations.ts +99 -0
- package/src/shared/utils/credit.ts +1 -1
- package/src/shared-kernel/application/hooks/index.ts +8 -0
- package/src/shared-kernel/application/hooks/use-feature-state.ts +107 -0
- package/src/shared-kernel/application/hooks/use-generation-handler.ts +110 -0
- package/src/shared-kernel/base-types/base-callbacks.types.ts +73 -0
- package/src/shared-kernel/base-types/base-feature-state.types.ts +77 -0
- package/src/shared-kernel/base-types/base-generation.types.ts +69 -0
- package/src/shared-kernel/base-types/index.ts +30 -0
- package/src/shared-kernel/domain/base-generation-strategy.ts +146 -0
- package/src/shared-kernel/domain/index.ts +7 -0
- package/src/shared-kernel/index.ts +17 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.ts +126 -0
- package/src/shared-kernel/infrastructure/validation/common-validators.types.ts +33 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.ts +52 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.types.ts +38 -0
- package/src/shared-kernel/infrastructure/validation/error-handler.utils.ts +79 -0
- package/src/shared-kernel/infrastructure/validation/index.ts +28 -0
- package/src/domains/background/infrastructure/services/job-poller.service.ts +0 -234
- package/src/domains/creations/presentation/hooks/useProcessingJobsPoller.ts +0 -256
- package/src/domains/generation/infrastructure/couple-generation-builder.ts +0 -374
- package/src/presentation/hooks/generation/orchestrator.ts +0 -276
- package/src/shared/hooks/factories/createGenerationHook.ts +0 -253
- package/src/shared/utils/calculations.util.ts +0 -366
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.3",
|
|
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",
|
|
@@ -69,9 +69,6 @@
|
|
|
69
69
|
"@gorhom/bottom-sheet": "^5.2.8",
|
|
70
70
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
71
71
|
"@react-native-community/slider": "^5.1.1",
|
|
72
|
-
"@react-navigation/bottom-tabs": "^7.9.0",
|
|
73
|
-
"@react-navigation/native": "^7.1.26",
|
|
74
|
-
"@react-navigation/stack": "^7.6.13",
|
|
75
72
|
"@tanstack/query-async-storage-persister": "^5.66.7",
|
|
76
73
|
"@tanstack/react-query": "^5.66.7",
|
|
77
74
|
"@tanstack/react-query-persist-client": "^5.66.7",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Services - Auth Interface
|
|
3
|
+
* Authentication service interface
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Auth service interface
|
|
8
|
+
* Handles user authentication
|
|
9
|
+
*/
|
|
10
|
+
export interface IAuthService {
|
|
11
|
+
/**
|
|
12
|
+
* Get current user ID
|
|
13
|
+
* @returns User ID or null if not authenticated
|
|
14
|
+
*/
|
|
15
|
+
getUserId: () => string | null;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if user is authenticated
|
|
19
|
+
*/
|
|
20
|
+
isAuthenticated: () => boolean;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Require authenticated user - throws if not authenticated
|
|
24
|
+
* @returns User ID
|
|
25
|
+
*/
|
|
26
|
+
requireAuth: () => string;
|
|
27
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Services - Composite Interface
|
|
3
|
+
* Combined app services interface
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { INetworkService } from "./app-services.interface";
|
|
7
|
+
import type { ICreditService } from "./app-services.interface";
|
|
8
|
+
import type { IPaywallService } from "./app-services.interface";
|
|
9
|
+
import type { IAuthService } from "./app-services-auth.interface";
|
|
10
|
+
import type { IAnalyticsService } from "./app-services-optional.interface";
|
|
11
|
+
import type { IFeatureUtils } from "./app-services-optional.interface";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Combined app services interface
|
|
15
|
+
* Apps implement this to provide all required services
|
|
16
|
+
*/
|
|
17
|
+
export interface IAppServices {
|
|
18
|
+
readonly network: INetworkService;
|
|
19
|
+
readonly credits: ICreditService;
|
|
20
|
+
readonly paywall: IPaywallService;
|
|
21
|
+
readonly auth: IAuthService;
|
|
22
|
+
readonly analytics?: IAnalyticsService;
|
|
23
|
+
readonly featureUtils?: IFeatureUtils;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Partial app services for optional configuration
|
|
28
|
+
*/
|
|
29
|
+
export type PartialAppServices = Partial<IAppServices>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App Services - Optional Interfaces
|
|
3
|
+
* Optional service interfaces (analytics, feature utils)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Analytics event data
|
|
8
|
+
*/
|
|
9
|
+
interface AnalyticsEventData {
|
|
10
|
+
readonly [key: string]: string | number | boolean | null | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Analytics service interface (optional)
|
|
15
|
+
* Tracks events for analytics
|
|
16
|
+
*/
|
|
17
|
+
export interface IAnalyticsService {
|
|
18
|
+
/**
|
|
19
|
+
* Track an event
|
|
20
|
+
* @param event - Event name
|
|
21
|
+
* @param data - Event data
|
|
22
|
+
*/
|
|
23
|
+
track: (event: string, data: AnalyticsEventData) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Feature utils interface (optional)
|
|
28
|
+
* Provides utility functions for AI features
|
|
29
|
+
*/
|
|
30
|
+
export interface IFeatureUtils {
|
|
31
|
+
/**
|
|
32
|
+
* Select image from gallery
|
|
33
|
+
* @returns Image URI or null if cancelled
|
|
34
|
+
*/
|
|
35
|
+
selectImage: () => Promise<string | null>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Save video to device library
|
|
39
|
+
* @param uri - Video URI to save
|
|
40
|
+
*/
|
|
41
|
+
saveVideo: (uri: string) => Promise<void>;
|
|
42
|
+
}
|
|
@@ -78,82 +78,3 @@ export interface IPaywallService {
|
|
|
78
78
|
*/
|
|
79
79
|
showPaywall: (requiredCredits: number) => void;
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Auth service interface
|
|
84
|
-
* Handles user authentication
|
|
85
|
-
*/
|
|
86
|
-
export interface IAuthService {
|
|
87
|
-
/**
|
|
88
|
-
* Get current user ID
|
|
89
|
-
* @returns User ID or null if not authenticated
|
|
90
|
-
*/
|
|
91
|
-
getUserId: () => string | null;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Check if user is authenticated
|
|
95
|
-
*/
|
|
96
|
-
isAuthenticated: () => boolean;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Require authenticated user - throws if not authenticated
|
|
100
|
-
* @returns User ID
|
|
101
|
-
*/
|
|
102
|
-
requireAuth: () => string;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Analytics event data
|
|
107
|
-
*/
|
|
108
|
-
interface AnalyticsEventData {
|
|
109
|
-
readonly [key: string]: string | number | boolean | null | undefined;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Analytics service interface (optional)
|
|
114
|
-
* Tracks events for analytics
|
|
115
|
-
*/
|
|
116
|
-
export interface IAnalyticsService {
|
|
117
|
-
/**
|
|
118
|
-
* Track an event
|
|
119
|
-
* @param event - Event name
|
|
120
|
-
* @param data - Event data
|
|
121
|
-
*/
|
|
122
|
-
track: (event: string, data: AnalyticsEventData) => void;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Feature utils interface (optional)
|
|
127
|
-
* Provides utility functions for AI features
|
|
128
|
-
*/
|
|
129
|
-
export interface IFeatureUtils {
|
|
130
|
-
/**
|
|
131
|
-
* Select image from gallery
|
|
132
|
-
* @returns Image URI or null if cancelled
|
|
133
|
-
*/
|
|
134
|
-
selectImage: () => Promise<string | null>;
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Save video to device library
|
|
138
|
-
* @param uri - Video URI to save
|
|
139
|
-
*/
|
|
140
|
-
saveVideo: (uri: string) => Promise<void>;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Combined app services interface
|
|
145
|
-
* Apps implement this to provide all required services
|
|
146
|
-
*/
|
|
147
|
-
export interface IAppServices {
|
|
148
|
-
readonly network: INetworkService;
|
|
149
|
-
readonly credits: ICreditService;
|
|
150
|
-
readonly paywall: IPaywallService;
|
|
151
|
-
readonly auth: IAuthService;
|
|
152
|
-
readonly analytics?: IAnalyticsService;
|
|
153
|
-
readonly featureUtils?: IFeatureUtils;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Partial app services for optional configuration
|
|
158
|
-
*/
|
|
159
|
-
export type PartialAppServices = Partial<IAppServices>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job Poller Service - Utility Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { checkStatusForErrors, isJobComplete } from "../utils/status-checker.util";
|
|
6
|
+
import { validateResult } from "../utils/result-validator.util";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Wrap a promise with abort signal support
|
|
10
|
+
* Rejects if signal is aborted before promise resolves
|
|
11
|
+
*/
|
|
12
|
+
export function withAbortSignal<T>(
|
|
13
|
+
promise: Promise<T>,
|
|
14
|
+
signal: AbortSignal | undefined,
|
|
15
|
+
timeoutMs?: number,
|
|
16
|
+
): Promise<T> {
|
|
17
|
+
if (!signal && !timeoutMs) {
|
|
18
|
+
return promise;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return new Promise<T>((resolve, reject) => {
|
|
22
|
+
// Handle abort signal
|
|
23
|
+
if (signal?.aborted) {
|
|
24
|
+
reject(new Error("Operation aborted"));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let isResolved = false;
|
|
29
|
+
const abortHandler = () => {
|
|
30
|
+
if (isResolved) return;
|
|
31
|
+
isResolved = true;
|
|
32
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
33
|
+
reject(new Error("Operation aborted"));
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
37
|
+
|
|
38
|
+
// Handle timeout
|
|
39
|
+
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
40
|
+
if (timeoutMs) {
|
|
41
|
+
timeoutId = setTimeout(() => {
|
|
42
|
+
if (isResolved) return;
|
|
43
|
+
isResolved = true;
|
|
44
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
45
|
+
reject(new Error(`Operation timeout after ${timeoutMs}ms`));
|
|
46
|
+
}, timeoutMs);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
promise
|
|
50
|
+
.then((result) => {
|
|
51
|
+
if (isResolved) return;
|
|
52
|
+
isResolved = true;
|
|
53
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
54
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
55
|
+
resolve(result);
|
|
56
|
+
})
|
|
57
|
+
.catch((error) => {
|
|
58
|
+
if (isResolved) return;
|
|
59
|
+
isResolved = true;
|
|
60
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
61
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
62
|
+
reject(error);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Validate request ID
|
|
69
|
+
*/
|
|
70
|
+
export function validateRequestId(requestId: string | undefined): { valid: boolean; error?: string } {
|
|
71
|
+
if (!requestId || typeof requestId !== "string" || requestId.trim() === "") {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
error: "Invalid requestId provided",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return { valid: true };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validate model
|
|
82
|
+
*/
|
|
83
|
+
export function validateModel(model: string | undefined): { valid: boolean; error?: string } {
|
|
84
|
+
if (!model || typeof model !== "string" || model.trim() === "") {
|
|
85
|
+
return {
|
|
86
|
+
valid: false,
|
|
87
|
+
error: "Invalid model provided",
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return { valid: true };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Log transient error during polling
|
|
95
|
+
*/
|
|
96
|
+
export function logTransientError(
|
|
97
|
+
attempt: number,
|
|
98
|
+
requestId: string,
|
|
99
|
+
model: string,
|
|
100
|
+
consecutiveErrors: number,
|
|
101
|
+
error: unknown
|
|
102
|
+
): void {
|
|
103
|
+
if (__DEV__) {
|
|
104
|
+
console.warn("[JobPoller] Transient error during polling", {
|
|
105
|
+
attempt: attempt + 1,
|
|
106
|
+
requestId,
|
|
107
|
+
model,
|
|
108
|
+
consecutiveErrors,
|
|
109
|
+
error: error instanceof Error ? error.message : String(error),
|
|
110
|
+
code: (error as { code?: string })?.code,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Log max consecutive errors reached
|
|
117
|
+
*/
|
|
118
|
+
export function logMaxConsecutiveErrors(
|
|
119
|
+
maxConsecutiveErrors: number,
|
|
120
|
+
requestId: string,
|
|
121
|
+
model: string
|
|
122
|
+
): void {
|
|
123
|
+
if (__DEV__) {
|
|
124
|
+
console.error("[JobPoller] Max consecutive errors reached", {
|
|
125
|
+
maxConsecutiveErrors,
|
|
126
|
+
requestId,
|
|
127
|
+
model,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { PollingConfig } from "../../../../domain/entities/polling.types";
|
|
7
|
-
import { calculatePollingInterval as calculateInterval } from "../../../../shared/utils/calculations
|
|
7
|
+
import { calculatePollingInterval as calculateInterval } from "../../../../shared/utils/calculations";
|
|
8
8
|
|
|
9
9
|
export interface IntervalOptions {
|
|
10
10
|
attempt: number;
|
|
@@ -2,7 +2,7 @@ import { useCallback, useRef, useState, useMemo } from "react";
|
|
|
2
2
|
import { usePendingJobs } from "./use-pending-jobs";
|
|
3
3
|
import { executeDirectGeneration, executeQueuedJob } from "../../infrastructure/executors/backgroundJobExecutor";
|
|
4
4
|
import { DEFAULT_QUEUE_CONFIG } from "../../domain/entities/job.types";
|
|
5
|
-
import { calculateFilteredCount } from "../../../../shared/utils/calculations
|
|
5
|
+
import { calculateFilteredCount } from "../../../../shared/utils/calculations";
|
|
6
6
|
import type {
|
|
7
7
|
UseBackgroundGenerationOptions,
|
|
8
8
|
UseBackgroundGenerationReturn,
|
package/src/domains/content-moderation/infrastructure/services/content-moderation.service.ts
CHANGED
|
@@ -17,7 +17,7 @@ import { imageModerator } from "./moderators/image.moderator";
|
|
|
17
17
|
import { videoModerator } from "./moderators/video.moderator";
|
|
18
18
|
import { voiceModerator } from "./moderators/voice.moderator";
|
|
19
19
|
import { rulesRegistry } from "../rules/rules-registry";
|
|
20
|
-
import { calculateConfidenceScore } from "../../../../shared/utils/calculations
|
|
20
|
+
import { calculateConfidenceScore } from "../../../../shared/utils/calculations";
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
interface ServiceConfig {
|
package/src/domains/content-moderation/infrastructure/services/moderators/image.moderator.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Image Content Moderator
|
|
3
|
-
* Validates and moderates image URIs
|
|
3
|
+
* Validates and moderates image URIs using shared validation utilities
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Violation } from "../../../domain/entities/moderation.types";
|
|
7
7
|
import { BaseModerator, type ModerationResult } from "./base.moderator";
|
|
8
8
|
import { DEFAULT_PROTOCOLS, DEFAULT_MAX_URI_LENGTH } from "../../constants/moderation.constants";
|
|
9
|
+
import { validateUrl, validateString, validateRequiredFields } from "../../../../shared-kernel/infrastructure/validation";
|
|
9
10
|
|
|
10
11
|
class ImageModerator extends BaseModerator {
|
|
11
12
|
private allowedProtocols: readonly string[] = DEFAULT_PROTOCOLS;
|
|
@@ -29,18 +30,43 @@ class ImageModerator extends BaseModerator {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
private validate(uri: string): Violation | null {
|
|
32
|
-
|
|
33
|
+
// Use shared validation utilities
|
|
34
|
+
const requiredValidation = validateRequiredFields({ uri }, ['uri']);
|
|
35
|
+
if (!requiredValidation.isValid) {
|
|
33
36
|
return this.createViolation("empty-uri", "Image Validation", "empty URI");
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
39
|
+
// Use shared URL validation
|
|
40
|
+
const urlValidation = validateUrl(uri);
|
|
41
|
+
if (!urlValidation.isValid) {
|
|
42
|
+
if (urlValidation.errors.required) {
|
|
43
|
+
return this.createViolation("empty-uri", "Image Validation", "empty URI");
|
|
44
|
+
}
|
|
45
|
+
if (urlValidation.errors.pattern) {
|
|
46
|
+
return this.createViolation(
|
|
47
|
+
"invalid-protocol",
|
|
48
|
+
"Image Validation",
|
|
49
|
+
"invalid protocol"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Use shared string validation for length
|
|
55
|
+
const lengthValidation = validateString(uri, {
|
|
56
|
+
maxLength: this.maxUriLength,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (!lengthValidation.isValid) {
|
|
60
|
+
if (lengthValidation.errors.maxLength) {
|
|
61
|
+
return this.createViolation(
|
|
62
|
+
"uri-too-long",
|
|
63
|
+
"Image Validation",
|
|
64
|
+
"URI too long"
|
|
65
|
+
);
|
|
66
|
+
}
|
|
42
67
|
}
|
|
43
68
|
|
|
69
|
+
// Custom protocol check
|
|
44
70
|
if (!this.hasValidProtocol(uri)) {
|
|
45
71
|
return this.createViolation(
|
|
46
72
|
"invalid-protocol",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Text Content Moderator
|
|
3
|
-
* Validates and moderates text content
|
|
3
|
+
* Validates and moderates text content using shared validation utilities
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Violation } from "../../../domain/entities/moderation.types";
|
|
@@ -10,6 +10,7 @@ import { BaseModerator, type ModerationResult } from "./base.moderator";
|
|
|
10
10
|
import { DEFAULT_MAX_TEXT_LENGTH } from "../../constants/moderation.constants";
|
|
11
11
|
import { containsMaliciousPatterns } from "../../utils/content-security.util";
|
|
12
12
|
import { containsPromptInjection } from "../../utils/prompt-injection.util";
|
|
13
|
+
import { validateString, validateRequiredFields } from "../../../../shared-kernel/infrastructure/validation";
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class TextModerator extends BaseModerator {
|
|
@@ -50,12 +51,22 @@ class TextModerator extends BaseModerator {
|
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
private validate(content: string): Violation | null {
|
|
53
|
-
|
|
54
|
+
// Use shared validation utilities
|
|
55
|
+
const requiredValidation = validateRequiredFields({ content }, ['content']);
|
|
56
|
+
if (!requiredValidation.isValid) {
|
|
54
57
|
return this.createViolation("empty-content", "Validation", "empty");
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
const stringValidation = validateString(content, {
|
|
61
|
+
required: true,
|
|
62
|
+
maxLength: this.maxLength,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (!stringValidation.isValid) {
|
|
66
|
+
if (stringValidation.errors.maxLength) {
|
|
67
|
+
return this.createViolation("too-long", "Validation", "length exceeded");
|
|
68
|
+
}
|
|
69
|
+
return this.createViolation("empty-content", "Validation", "empty");
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
if (this.containsMaliciousCode(content)) {
|
package/src/domains/content-moderation/infrastructure/services/moderators/video.moderator.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Video Content Moderator
|
|
3
|
-
* Validates and moderates video URIs
|
|
3
|
+
* Validates and moderates video URIs using shared validation utilities
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Violation } from "../../../domain/entities/moderation.types";
|
|
7
7
|
import { BaseModerator, type ModerationResult } from "./base.moderator";
|
|
8
8
|
import { VIDEO_PROTOCOLS, DEFAULT_MAX_URI_LENGTH } from "../../constants/moderation.constants";
|
|
9
|
+
import { validateUrl, validateString, validateRequiredFields } from "../../../../shared-kernel/infrastructure/validation";
|
|
9
10
|
|
|
10
11
|
class VideoModerator extends BaseModerator {
|
|
11
12
|
private allowedProtocols: readonly string[] = VIDEO_PROTOCOLS;
|
|
@@ -29,18 +30,43 @@ class VideoModerator extends BaseModerator {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
private validate(uri: string): Violation | null {
|
|
32
|
-
|
|
33
|
+
// Use shared validation utilities
|
|
34
|
+
const requiredValidation = validateRequiredFields({ uri }, ['uri']);
|
|
35
|
+
if (!requiredValidation.isValid) {
|
|
33
36
|
return this.createViolation("empty-uri", "Video Validation", "empty URI");
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
39
|
+
// Use shared URL validation
|
|
40
|
+
const urlValidation = validateUrl(uri);
|
|
41
|
+
if (!urlValidation.isValid) {
|
|
42
|
+
if (urlValidation.errors.required) {
|
|
43
|
+
return this.createViolation("empty-uri", "Video Validation", "empty URI");
|
|
44
|
+
}
|
|
45
|
+
if (urlValidation.errors.pattern) {
|
|
46
|
+
return this.createViolation(
|
|
47
|
+
"invalid-protocol",
|
|
48
|
+
"Video Validation",
|
|
49
|
+
"invalid protocol"
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Use shared string validation for length
|
|
55
|
+
const lengthValidation = validateString(uri, {
|
|
56
|
+
maxLength: this.maxUriLength,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (!lengthValidation.isValid) {
|
|
60
|
+
if (lengthValidation.errors.maxLength) {
|
|
61
|
+
return this.createViolation(
|
|
62
|
+
"uri-too-long",
|
|
63
|
+
"Video Validation",
|
|
64
|
+
"URI too long"
|
|
65
|
+
);
|
|
66
|
+
}
|
|
42
67
|
}
|
|
43
68
|
|
|
69
|
+
// Custom protocol check
|
|
44
70
|
if (!this.hasValidProtocol(uri)) {
|
|
45
71
|
return this.createViolation(
|
|
46
72
|
"invalid-protocol",
|
package/src/domains/content-moderation/infrastructure/services/moderators/voice.moderator.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Voice Content Moderator
|
|
3
|
-
* Validates and moderates voice/TTS text content
|
|
3
|
+
* Validates and moderates voice/TTS text content using shared validation utilities
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Violation } from "../../../domain/entities/moderation.types";
|
|
@@ -8,6 +8,7 @@ import { patternMatcherService } from "../pattern-matcher.service";
|
|
|
8
8
|
import { rulesRegistry } from "../../rules/rules-registry";
|
|
9
9
|
import { BaseModerator, type ModerationResult } from "./base.moderator";
|
|
10
10
|
import { env } from "../../../../../infrastructure/config/env.config";
|
|
11
|
+
import { validateString, validateRequiredFields } from "../../../../shared-kernel/infrastructure/validation";
|
|
11
12
|
|
|
12
13
|
class VoiceModerator extends BaseModerator {
|
|
13
14
|
private maxLength = env.moderationVoiceMaxLength;
|
|
@@ -27,16 +28,26 @@ class VoiceModerator extends BaseModerator {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
private validate(text: string): Violation | null {
|
|
30
|
-
|
|
31
|
+
// Use shared validation utilities
|
|
32
|
+
const requiredValidation = validateRequiredFields({ text }, ['text']);
|
|
33
|
+
if (!requiredValidation.isValid) {
|
|
31
34
|
return this.createViolation("empty-text", "Voice Validation", "empty");
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const stringValidation = validateString(text, {
|
|
38
|
+
required: true,
|
|
39
|
+
maxLength: this.maxLength,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!stringValidation.isValid) {
|
|
43
|
+
if (stringValidation.errors.maxLength) {
|
|
44
|
+
return this.createViolation(
|
|
45
|
+
"too-long",
|
|
46
|
+
"Voice Validation",
|
|
47
|
+
"length exceeded"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return this.createViolation("empty-text", "Voice Validation", "empty");
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
return null;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creation Categories - Constants
|
|
3
|
+
* Constants for creation type categories
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CreationTypeId } from "./creation-types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Image-related creation types
|
|
10
|
+
*/
|
|
11
|
+
export const IMAGE_CREATION_TYPES: CreationTypeId[] = [
|
|
12
|
+
"text-to-image",
|
|
13
|
+
"imagine",
|
|
14
|
+
"wardrobe",
|
|
15
|
+
"historical-wardrobe",
|
|
16
|
+
"upscale",
|
|
17
|
+
"remove-background",
|
|
18
|
+
"photo-restore",
|
|
19
|
+
"inpainting",
|
|
20
|
+
"style-transfer",
|
|
21
|
+
"colorization",
|
|
22
|
+
"face-swap",
|
|
23
|
+
"object-removal",
|
|
24
|
+
"background-replacement",
|
|
25
|
+
"ai-brush",
|
|
26
|
+
"hd-touch-up",
|
|
27
|
+
"anime-selfie",
|
|
28
|
+
"aging",
|
|
29
|
+
"headshot",
|
|
30
|
+
"retouch",
|
|
31
|
+
"magic-edit",
|
|
32
|
+
"color-grading",
|
|
33
|
+
"art-style",
|
|
34
|
+
"mood-filter",
|
|
35
|
+
"face-expression",
|
|
36
|
+
"scene-composer",
|
|
37
|
+
"ai-background",
|
|
38
|
+
"effects",
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Video-related creation types (core types only)
|
|
43
|
+
* NOTE: All other video types (scenarios, etc.)
|
|
44
|
+
* are dynamically determined by output content via isVideoUrl()
|
|
45
|
+
*/
|
|
46
|
+
export const VIDEO_CREATION_TYPES: CreationTypeId[] = [
|
|
47
|
+
"text-to-video",
|
|
48
|
+
"image-to-video",
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* All creation types
|
|
53
|
+
*/
|
|
54
|
+
export const ALL_CREATION_TYPES: CreationTypeId[] = [
|
|
55
|
+
...IMAGE_CREATION_TYPES,
|
|
56
|
+
...VIDEO_CREATION_TYPES,
|
|
57
|
+
];
|