@umituz/react-native-ai-generation-content 1.65.1 → 1.65.2
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/domain/constants/processing-modes-catalog.constants.ts +97 -0
- package/src/domain/constants/processing-modes-filters.ts +34 -0
- package/src/domain/constants/processing-modes-getters.ts +20 -0
- package/src/domain/constants/processing-modes.constants.ts +8 -134
- package/src/domain/entities/feature-flow-config.types.ts +17 -0
- package/src/domain/entities/flow-actions.types.ts +26 -0
- package/src/domain/entities/flow-config-data.types.ts +41 -0
- package/src/domain/entities/flow-config.types.ts +17 -169
- package/src/domain/entities/flow-configuration.types.ts +44 -0
- package/src/domain/entities/flow-state.types.ts +30 -0
- package/src/domain/entities/flow-step.types.ts +56 -0
- package/src/domain/entities/scenario-step-config.types.ts +32 -0
- package/src/domain/entities/step-config.types.ts +14 -129
- package/src/domain/entities/step-definition.types.ts +50 -0
- package/src/domain/entities/step-input-config.types.ts +36 -0
- package/src/domain/entities/step-upload-config.types.ts +17 -0
- package/src/domain/interfaces/ai-provider-capabilities.types.ts +27 -0
- package/src/domain/interfaces/ai-provider-config.types.ts +30 -0
- package/src/domain/interfaces/ai-provider-feature-types.ts +22 -0
- package/src/domain/interfaces/ai-provider-input.types.ts +28 -0
- package/src/domain/interfaces/ai-provider-progress.types.ts +37 -0
- package/src/domain/interfaces/ai-provider-status.types.ts +41 -0
- package/src/domain/interfaces/ai-provider.interface.ts +32 -142
- package/src/domain/types/result-constructors.ts +20 -0
- package/src/domain/types/result-guards.ts +20 -0
- package/src/domain/types/result-transformers.ts +36 -0
- package/src/domain/types/result-type-definitions.ts +27 -0
- package/src/domain/types/result-unwrappers.ts +28 -0
- package/src/domain/types/result.types.ts +11 -100
- package/src/domains/background/infrastructure/utils/polling-interval.util.ts +3 -8
- package/src/domains/background/infrastructure/utils/result-validation-logic.ts +88 -0
- package/src/domains/background/infrastructure/utils/result-validator-constants.ts +18 -0
- package/src/domains/background/infrastructure/utils/result-validator.types.ts +16 -0
- package/src/domains/background/infrastructure/utils/result-validator.util.ts +8 -109
- package/src/domains/background/infrastructure/utils/status-checker.types.ts +11 -0
- package/src/domains/background/infrastructure/utils/status-checker.util.ts +9 -119
- package/src/domains/background/infrastructure/utils/status-error-detector.ts +61 -0
- package/src/domains/background/infrastructure/utils/status-extraction-helpers.ts +25 -0
- package/src/domains/background/infrastructure/utils/status-predicates.ts +37 -0
- package/src/domains/creations/domain-exports.ts +79 -0
- package/src/domains/creations/index.ts +9 -169
- package/src/domains/creations/infrastructure-exports.ts +9 -0
- package/src/domains/creations/presentation-exports.ts +59 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.helpers.ts +81 -0
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.ts +4 -100
- package/src/domains/generation/infrastructure/executors/text-to-image-executor.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/use-flow-store.types.ts +19 -0
- package/src/domains/generation/infrastructure/flow/useFlowStore.ts +33 -65
- package/src/domains/generation/wizard/domain/entities/wizard-config-builder.ts +75 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature-config.types.ts +29 -0
- package/src/domains/generation/wizard/domain/entities/wizard-feature.types.ts +9 -114
- package/src/domains/generation/wizard/domain/entities/wizard-presets.constants.ts +23 -0
- package/src/domains/generation/wizard/infrastructure/strategies/shared/unified-prompt-builder.ts +1 -1
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence-factory.ts +33 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.types.ts +22 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-persistence.util.ts +11 -135
- package/src/domains/generation/wizard/infrastructure/utils/creation-save-operations.ts +48 -0
- package/src/domains/generation/wizard/infrastructure/utils/creation-update-operations.ts +72 -0
- package/src/domains/generation/wizard/presentation/hooks/use-video-queue-generation.types.ts +21 -0
- package/src/domains/generation/wizard/presentation/hooks/useVideoQueueGeneration.ts +14 -35
- package/src/domains/image-to-video/domain/types/image-to-video-callbacks.types.ts +33 -0
- package/src/domains/image-to-video/domain/types/image-to-video-config.types.ts +29 -0
- package/src/domains/image-to-video/domain/types/image-to-video-request.types.ts +31 -0
- package/src/domains/image-to-video/domain/types/image-to-video-result.types.ts +17 -0
- package/src/domains/image-to-video/domain/types/image-to-video-state.types.ts +24 -0
- package/src/domains/image-to-video/domain/types/image-to-video.types.ts +24 -114
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.ts +26 -99
- package/src/domains/image-to-video/infrastructure/services/image-to-video-executor.types.ts +15 -0
- package/src/domains/prompts/domain/base/constants.ts +47 -0
- package/src/domains/prompts/domain/base/creators.ts +76 -0
- package/src/domains/prompts/domain/base/types.ts +10 -0
- package/src/domains/prompts/domain/entities/MultiPersonPromptStructure.ts +1 -1
- package/src/domains/prompts/index.ts +4 -2
- package/src/domains/prompts/infrastructure/services/ImagePromptBuilder.ts +2 -72
- package/src/domains/prompts/infrastructure/services/image-prompt-builder.types.ts +17 -0
- package/src/domains/result-preview/presentation/types/result-components.types.ts +47 -0
- package/src/domains/result-preview/presentation/types/result-creation.types.ts +14 -0
- package/src/domains/result-preview/presentation/types/result-data.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-hooks.types.ts +35 -0
- package/src/domains/result-preview/presentation/types/result-preview.types.ts +19 -182
- package/src/domains/result-preview/presentation/types/result-screen.types.ts +69 -0
- package/src/domains/text-to-image/domain-exports.ts +50 -0
- package/src/domains/text-to-image/index.ts +11 -102
- package/src/domains/text-to-image/infrastructure-exports.ts +6 -0
- package/src/domains/text-to-image/presentation/hooks/useFormState.ts +39 -24
- package/src/domains/text-to-image/presentation/hooks/useGeneration.ts +5 -3
- package/src/domains/text-to-image/presentation-exports.ts +41 -0
- package/src/domains/text-to-video/domain/types/action-component.types.ts +15 -0
- package/src/domains/text-to-video/domain/types/component.types.ts +16 -103
- package/src/domains/text-to-video/domain/types/content-component.types.ts +30 -0
- package/src/domains/text-to-video/domain/types/panel-component.types.ts +24 -0
- package/src/domains/text-to-video/domain/types/selector-component.types.ts +31 -0
- package/src/domains/text-to-video/domain/types/tab-component.types.ts +26 -0
- package/src/index.ts +0 -10
- package/src/infrastructure/executors/base-executor.ts +40 -112
- package/src/infrastructure/executors/base-executor.types.ts +10 -0
- package/src/infrastructure/http/http-client-methods.ts +73 -0
- package/src/infrastructure/http/http-client.util.ts +8 -163
- package/src/infrastructure/http/http-fetch-handler.ts +53 -0
- package/src/infrastructure/http/http-methods.constants.ts +23 -0
- package/src/infrastructure/http/http-request-executor.ts +49 -0
- package/src/infrastructure/http/http-response-parser.ts +53 -0
- package/src/infrastructure/orchestration/GenerationOrchestrator.ts +8 -43
- package/src/infrastructure/utils/classifier-helpers.ts +36 -0
- package/src/infrastructure/utils/content-validators.ts +92 -0
- package/src/infrastructure/utils/domain-guards.ts +22 -0
- package/src/infrastructure/utils/error-classification.ts +122 -0
- package/src/infrastructure/utils/error-classifier.util.ts +8 -181
- package/src/infrastructure/utils/error-classifiers.ts +49 -0
- package/src/infrastructure/utils/error-extractors.ts +42 -0
- package/src/infrastructure/utils/error-factory.ts +25 -0
- package/src/infrastructure/utils/error-handlers.ts +51 -0
- package/src/infrastructure/utils/error-handling.util.ts +7 -186
- package/src/infrastructure/utils/error-message-extractor.util.ts +10 -172
- package/src/infrastructure/utils/error-retry.ts +44 -0
- package/src/infrastructure/utils/error-types.ts +23 -0
- package/src/infrastructure/utils/extraction-types.ts +37 -0
- package/src/infrastructure/utils/fal-error-checker.ts +44 -0
- package/src/infrastructure/utils/general-validators.ts +64 -0
- package/src/infrastructure/utils/id-validators.ts +39 -0
- package/src/infrastructure/utils/message-extractor.ts +89 -0
- package/src/infrastructure/utils/primitive-guards.ts +66 -0
- package/src/infrastructure/utils/result-polling.ts +39 -0
- package/src/infrastructure/utils/structure-guards.ts +75 -0
- package/src/infrastructure/utils/type-guards.util.ts +22 -149
- package/src/infrastructure/utils/validation-types.ts +8 -0
- package/src/infrastructure/utils/validation.util.ts +14 -184
- package/src/presentation/hooks/ai-feature-callbacks-auth.hooks.ts +43 -0
- package/src/presentation/hooks/ai-feature-callbacks-cost.hooks.ts +56 -0
- package/src/presentation/hooks/ai-feature-callbacks-execution.hooks.ts +66 -0
- package/src/presentation/hooks/ai-feature-callbacks.types.ts +69 -0
- package/src/presentation/hooks/generation/use-image-generation.types.ts +39 -0
- package/src/presentation/hooks/generation/useImageGeneration.ts +33 -99
- package/src/presentation/hooks/generation-flow-navigation.ts +58 -0
- package/src/presentation/hooks/generation-flow-updates.ts +67 -0
- package/src/presentation/hooks/generation-flow.types.ts +32 -0
- package/src/presentation/hooks/useAIFeatureCallbacks.ts +48 -138
- package/src/presentation/hooks/useGenerationFlow.ts +40 -136
- package/src/presentation/types/flow-config.types.ts +9 -140
- package/src/presentation/types/flow-generation-config.types.ts +25 -0
- package/src/presentation/types/flow-state.types.ts +16 -0
- package/src/presentation/types/flow-step-configs.types.ts +48 -0
- package/src/presentation/types/flow-step-data.types.ts +24 -0
- package/src/presentation/types/result-actions.types.ts +50 -0
- package/src/presentation/types/result-config.types.ts +22 -171
- package/src/presentation/types/result-header.types.ts +44 -0
- package/src/presentation/types/result-image.types.ts +29 -0
- package/src/presentation/types/result-layout.types.ts +26 -0
- package/src/presentation/types/result-story.types.ts +42 -0
- package/src/domains/prompts/domain/entities/BasePromptStructure.ts +0 -168
- package/src/exports/domains.ts +0 -149
|
@@ -1,167 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP Client Utilities
|
|
2
|
+
* HTTP Client Utilities - Barrel Export
|
|
3
3
|
* Core HTTP request handling with error handling and retry logic
|
|
4
|
+
*
|
|
5
|
+
* Architecture:
|
|
6
|
+
* - Domain: HTTP methods, content types (constants)
|
|
7
|
+
* - Infrastructure: Request execution, response parsing, error handling
|
|
4
8
|
*/
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { createTimeoutController } from "./timeout.util";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Makes an HTTP request with error handling and retry logic
|
|
13
|
-
* @param url - Request URL
|
|
14
|
-
* @param options - Request options
|
|
15
|
-
* @returns API response with data or error
|
|
16
|
-
*/
|
|
17
|
-
export async function fetchWithTimeout<T>(
|
|
18
|
-
url: string,
|
|
19
|
-
options: RequestOptions = {}
|
|
20
|
-
): Promise<ApiResponse<T>> {
|
|
21
|
-
const {
|
|
22
|
-
timeout = env.apiDefaultTimeoutMs,
|
|
23
|
-
retries = 0,
|
|
24
|
-
headers = {},
|
|
25
|
-
...fetchOptions
|
|
26
|
-
} = options;
|
|
27
|
-
|
|
28
|
-
const controller = createTimeoutController(timeout);
|
|
29
|
-
|
|
30
|
-
const operation = async (): Promise<T> => {
|
|
31
|
-
const response = await fetch(url, {
|
|
32
|
-
...fetchOptions,
|
|
33
|
-
headers: {
|
|
34
|
-
"Content-Type": "application/json",
|
|
35
|
-
...headers,
|
|
36
|
-
},
|
|
37
|
-
signal: controller?.signal,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (!response.ok) {
|
|
41
|
-
const errorText = await response.text().catch(() => "Unknown error");
|
|
42
|
-
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const contentType = response.headers.get("content-type");
|
|
46
|
-
if (contentType?.includes("application/json")) {
|
|
47
|
-
return response.json();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return response.text() as T;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const result = await withErrorHandling(
|
|
54
|
-
async () => {
|
|
55
|
-
if (retries > 0) {
|
|
56
|
-
return retryWithBackoff(operation, {
|
|
57
|
-
maxRetries: retries,
|
|
58
|
-
delayMs: env.apiRetryDelayMs,
|
|
59
|
-
shouldRetry: (error) => isNetworkError(error),
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
return operation();
|
|
63
|
-
},
|
|
64
|
-
(error) => {
|
|
65
|
-
console.error("[API Client] Request failed:", error);
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
if (result.error) {
|
|
70
|
-
return {
|
|
71
|
-
data: null,
|
|
72
|
-
error: getErrorMessage(result.error),
|
|
73
|
-
status: 0,
|
|
74
|
-
headers: new Headers(),
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
data: result.data ?? null,
|
|
80
|
-
error: null,
|
|
81
|
-
status: 200,
|
|
82
|
-
headers: new Headers(),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Makes a GET request
|
|
88
|
-
* @param url - Request URL
|
|
89
|
-
* @param options - Request options
|
|
90
|
-
* @returns API response
|
|
91
|
-
*/
|
|
92
|
-
export async function get<T>(
|
|
93
|
-
url: string,
|
|
94
|
-
options: Omit<RequestOptions, "method" | "body"> = {}
|
|
95
|
-
): Promise<ApiResponse<T>> {
|
|
96
|
-
return fetchWithTimeout<T>(url, { ...options, method: "GET" });
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Makes a POST request
|
|
101
|
-
* @param url - Request URL
|
|
102
|
-
* @param data - Request body data
|
|
103
|
-
* @param options - Request options
|
|
104
|
-
* @returns API response
|
|
105
|
-
*/
|
|
106
|
-
export async function post<T>(
|
|
107
|
-
url: string,
|
|
108
|
-
data: unknown,
|
|
109
|
-
options: Omit<RequestOptions, "method"> = {}
|
|
110
|
-
): Promise<ApiResponse<T>> {
|
|
111
|
-
return fetchWithTimeout<T>(url, {
|
|
112
|
-
...options,
|
|
113
|
-
method: "POST",
|
|
114
|
-
body: JSON.stringify(data),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Makes a PUT request
|
|
120
|
-
* @param url - Request URL
|
|
121
|
-
* @param data - Request body data
|
|
122
|
-
* @param options - Request options
|
|
123
|
-
* @returns API response
|
|
124
|
-
*/
|
|
125
|
-
export async function put<T>(
|
|
126
|
-
url: string,
|
|
127
|
-
data: unknown,
|
|
128
|
-
options: Omit<RequestOptions, "method"> = {}
|
|
129
|
-
): Promise<ApiResponse<T>> {
|
|
130
|
-
return fetchWithTimeout<T>(url, {
|
|
131
|
-
...options,
|
|
132
|
-
method: "PUT",
|
|
133
|
-
body: JSON.stringify(data),
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Makes a DELETE request
|
|
139
|
-
* @param url - Request URL
|
|
140
|
-
* @param options - Request options
|
|
141
|
-
* @returns API response
|
|
142
|
-
*/
|
|
143
|
-
export async function del<T>(
|
|
144
|
-
url: string,
|
|
145
|
-
options: Omit<RequestOptions, "method" | "body"> = {}
|
|
146
|
-
): Promise<ApiResponse<T>> {
|
|
147
|
-
return fetchWithTimeout<T>(url, { ...options, method: "DELETE" });
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Makes a PATCH request
|
|
152
|
-
* @param url - Request URL
|
|
153
|
-
* @param data - Request body data
|
|
154
|
-
* @param options - Request options
|
|
155
|
-
* @returns API response
|
|
156
|
-
*/
|
|
157
|
-
export async function patch<T>(
|
|
158
|
-
url: string,
|
|
159
|
-
data: unknown,
|
|
160
|
-
options: Omit<RequestOptions, "method"> = {}
|
|
161
|
-
): Promise<ApiResponse<T>> {
|
|
162
|
-
return fetchWithTimeout<T>(url, {
|
|
163
|
-
...options,
|
|
164
|
-
method: "PATCH",
|
|
165
|
-
body: JSON.stringify(data),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
10
|
+
export { HTTP_METHOD, HTTP_CONTENT_TYPE, DEFAULT_HEADERS, type HttpMethod } from "./http-methods.constants";
|
|
11
|
+
export { fetchWithTimeout } from "./http-fetch-handler";
|
|
12
|
+
export { get, post, put, del, patch } from "./http-client-methods";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Fetch Handler
|
|
3
|
+
* Infrastructure: Orchestrates request execution with error handling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { withErrorHandling, getErrorMessage, retryWithBackoff, isNetworkError } from "../utils/error-handling.util";
|
|
7
|
+
import { env } from "../config/env.config";
|
|
8
|
+
import type { RequestOptions, ApiResponse } from "./api-client.types";
|
|
9
|
+
import { executeRequest, isSuccessResponse, extractErrorMessage } from "./http-request-executor";
|
|
10
|
+
import { parseResponse, createSuccessResponse, createErrorResponse } from "./http-response-parser";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fetches data with timeout, retry, and error handling
|
|
14
|
+
*/
|
|
15
|
+
export async function fetchWithTimeout<T>(
|
|
16
|
+
url: string,
|
|
17
|
+
options: RequestOptions = {}
|
|
18
|
+
): Promise<ApiResponse<T>> {
|
|
19
|
+
const { retries = 0 } = options;
|
|
20
|
+
|
|
21
|
+
const operation = async (): Promise<T> => {
|
|
22
|
+
const response = await executeRequest<T>(url, options);
|
|
23
|
+
|
|
24
|
+
if (!isSuccessResponse(response)) {
|
|
25
|
+
const errorMessage = await extractErrorMessage(response);
|
|
26
|
+
throw new Error(errorMessage);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return parseResponse<T>(response);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const result = await withErrorHandling(
|
|
33
|
+
async () => {
|
|
34
|
+
if (retries > 0) {
|
|
35
|
+
return retryWithBackoff(operation, {
|
|
36
|
+
maxRetries: retries,
|
|
37
|
+
delayMs: env.apiRetryDelayMs,
|
|
38
|
+
shouldRetry: (error) => isNetworkError(error),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return operation();
|
|
42
|
+
},
|
|
43
|
+
(error) => {
|
|
44
|
+
console.error("[API Client] Request failed:", error);
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (result.error) {
|
|
49
|
+
return createErrorResponse(getErrorMessage(result.error));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return createSuccessResponse(result.data ?? null as T);
|
|
53
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Methods Constants
|
|
3
|
+
* Domain knowledge: Standard HTTP methods
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const HTTP_METHOD = {
|
|
7
|
+
GET: "GET",
|
|
8
|
+
POST: "POST",
|
|
9
|
+
PUT: "PUT",
|
|
10
|
+
DELETE: "DELETE",
|
|
11
|
+
PATCH: "PATCH",
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export type HttpMethod = typeof HTTP_METHOD[keyof typeof HTTP_METHOD];
|
|
15
|
+
|
|
16
|
+
export const HTTP_CONTENT_TYPE = {
|
|
17
|
+
JSON: "application/json",
|
|
18
|
+
TEXT: "text/plain",
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_HEADERS = {
|
|
22
|
+
"Content-Type": HTTP_CONTENT_TYPE.JSON,
|
|
23
|
+
} as const;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Request Executor
|
|
3
|
+
* Infrastructure: Handles low-level fetch operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { env } from "../config/env.config";
|
|
7
|
+
import { createTimeoutController } from "./timeout.util";
|
|
8
|
+
import { DEFAULT_HEADERS } from "./http-methods.constants";
|
|
9
|
+
import type { RequestOptions } from "./api-client.types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Executes HTTP request with timeout
|
|
13
|
+
*/
|
|
14
|
+
export async function executeRequest<T>(
|
|
15
|
+
url: string,
|
|
16
|
+
options: RequestOptions = {}
|
|
17
|
+
): Promise<Response> {
|
|
18
|
+
const {
|
|
19
|
+
timeout = env.apiDefaultTimeoutMs,
|
|
20
|
+
headers = {},
|
|
21
|
+
...fetchOptions
|
|
22
|
+
} = options;
|
|
23
|
+
|
|
24
|
+
const controller = createTimeoutController(timeout);
|
|
25
|
+
|
|
26
|
+
return fetch(url, {
|
|
27
|
+
...fetchOptions,
|
|
28
|
+
headers: {
|
|
29
|
+
...DEFAULT_HEADERS,
|
|
30
|
+
...headers,
|
|
31
|
+
},
|
|
32
|
+
signal: controller?.signal,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Checks if response is successful
|
|
38
|
+
*/
|
|
39
|
+
export function isSuccessResponse(response: Response): boolean {
|
|
40
|
+
return response.ok;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extracts error message from failed response
|
|
45
|
+
*/
|
|
46
|
+
export async function extractErrorMessage(response: Response): Promise<string> {
|
|
47
|
+
const errorText = await response.text().catch(() => "Unknown error");
|
|
48
|
+
return `HTTP ${response.status}: ${errorText}`;
|
|
49
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Response Parser
|
|
3
|
+
* Infrastructure: Parses HTTP responses to typed data
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { HTTP_CONTENT_TYPE } from "./http-methods.constants";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parses response based on content type
|
|
10
|
+
*/
|
|
11
|
+
export async function parseResponse<T>(response: Response): Promise<T> {
|
|
12
|
+
const contentType = response.headers.get("content-type");
|
|
13
|
+
|
|
14
|
+
if (contentType?.includes(HTTP_CONTENT_TYPE.JSON)) {
|
|
15
|
+
return response.json();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return response.text() as T;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates successful API response
|
|
23
|
+
*/
|
|
24
|
+
export function createSuccessResponse<T>(data: T): {
|
|
25
|
+
data: T;
|
|
26
|
+
error: null;
|
|
27
|
+
status: number;
|
|
28
|
+
headers: Headers;
|
|
29
|
+
} {
|
|
30
|
+
return {
|
|
31
|
+
data,
|
|
32
|
+
error: null,
|
|
33
|
+
status: 200,
|
|
34
|
+
headers: new Headers(),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates error API response
|
|
40
|
+
*/
|
|
41
|
+
export function createErrorResponse(errorMessage: string): {
|
|
42
|
+
data: null;
|
|
43
|
+
error: string;
|
|
44
|
+
status: number;
|
|
45
|
+
headers: Headers;
|
|
46
|
+
} {
|
|
47
|
+
return {
|
|
48
|
+
data: null,
|
|
49
|
+
error: errorMessage,
|
|
50
|
+
status: 0,
|
|
51
|
+
headers: new Headers(),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI Generation Orchestrator
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Generic orchestrator for 100+ apps with dependency injection
|
|
6
|
-
* Handles: Network check, content moderation, credit processing, refunds
|
|
3
|
+
* Orchestrates AI generation business operations
|
|
7
4
|
*/
|
|
8
5
|
|
|
9
6
|
import {
|
|
10
7
|
contentModerationService,
|
|
11
8
|
ContentPolicyViolationError,
|
|
12
9
|
} from "../../domains/content-moderation";
|
|
13
|
-
import type {
|
|
14
|
-
OrchestratorConfig,
|
|
15
|
-
GenerationMetadata,
|
|
16
|
-
} from "./orchestrator.types";
|
|
10
|
+
import type { OrchestratorConfig, GenerationMetadata } from "./orchestrator.types";
|
|
17
11
|
import type { GenerationCapability } from "../../domain/entities/generation.types";
|
|
18
12
|
import {
|
|
19
13
|
NetworkUnavailableError,
|
|
@@ -21,8 +15,6 @@ import {
|
|
|
21
15
|
AuthenticationRequiredError,
|
|
22
16
|
} from "./orchestrator.errors";
|
|
23
17
|
|
|
24
|
-
declare const __DEV__: boolean;
|
|
25
|
-
|
|
26
18
|
export class GenerationOrchestrator {
|
|
27
19
|
constructor(private config: OrchestratorConfig) {}
|
|
28
20
|
|
|
@@ -84,8 +76,7 @@ export class GenerationOrchestrator {
|
|
|
84
76
|
const creditCost = this.calculateCreditCost(capability, metadata);
|
|
85
77
|
const actualUserId = this.requireAuthenticatedUser();
|
|
86
78
|
|
|
87
|
-
const currentCredits =
|
|
88
|
-
await this.config.creditService.getBalance(actualUserId);
|
|
79
|
+
const currentCredits = await this.config.creditService.getBalance(actualUserId);
|
|
89
80
|
|
|
90
81
|
if (currentCredits < creditCost) {
|
|
91
82
|
this.config.paywallService.show(creditCost);
|
|
@@ -102,13 +93,9 @@ export class GenerationOrchestrator {
|
|
|
102
93
|
const actualUserId = this.requireAuthenticatedUser();
|
|
103
94
|
const creditCost = this.calculateCreditCost(capability, metadata);
|
|
104
95
|
|
|
105
|
-
const currentCredits =
|
|
106
|
-
await this.config.creditService.getBalance(actualUserId);
|
|
96
|
+
const currentCredits = await this.config.creditService.getBalance(actualUserId);
|
|
107
97
|
|
|
108
|
-
const success = await this.config.creditService.deduct(
|
|
109
|
-
actualUserId,
|
|
110
|
-
creditCost,
|
|
111
|
-
);
|
|
98
|
+
const success = await this.config.creditService.deduct(actualUserId, creditCost);
|
|
112
99
|
|
|
113
100
|
if (!success) {
|
|
114
101
|
this.config.paywallService.show(creditCost);
|
|
@@ -118,10 +105,7 @@ export class GenerationOrchestrator {
|
|
|
118
105
|
return creditCost;
|
|
119
106
|
}
|
|
120
107
|
|
|
121
|
-
async refundCreditsIfApplicable(
|
|
122
|
-
amount: number,
|
|
123
|
-
error: unknown,
|
|
124
|
-
): Promise<void> {
|
|
108
|
+
async refundCreditsIfApplicable(amount: number, error: unknown): Promise<void> {
|
|
125
109
|
if (amount <= 0) return;
|
|
126
110
|
|
|
127
111
|
const isNonRefundable =
|
|
@@ -132,31 +116,12 @@ export class GenerationOrchestrator {
|
|
|
132
116
|
error.message.toLowerCase().includes("cancelled") ||
|
|
133
117
|
error.message.toLowerCase().includes("user cancel")));
|
|
134
118
|
|
|
135
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
136
|
-
console.log("[GenerationOrchestrator] Refund check:", {
|
|
137
|
-
amount,
|
|
138
|
-
isNonRefundable,
|
|
139
|
-
errorType: error instanceof Error ? error.name : typeof error,
|
|
140
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
119
|
if (!isNonRefundable) {
|
|
145
120
|
try {
|
|
146
121
|
const actualUserId = this.requireAuthenticatedUser();
|
|
147
|
-
|
|
148
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
149
|
-
console.log("[GenerationOrchestrator] Refunding credits:", {
|
|
150
|
-
userId: actualUserId,
|
|
151
|
-
amount,
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
122
|
await this.config.creditService.add(actualUserId, amount);
|
|
156
|
-
} catch
|
|
157
|
-
|
|
158
|
-
console.error("[GenerationOrchestrator] Refund failed:", refundErr);
|
|
159
|
-
}
|
|
123
|
+
} catch {
|
|
124
|
+
// Silently fail refund - non-critical operation
|
|
160
125
|
}
|
|
161
126
|
}
|
|
162
127
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Classifier Helper Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { AIErrorInfo } from "../../domain/entities";
|
|
6
|
+
|
|
7
|
+
declare const __DEV__: boolean;
|
|
8
|
+
|
|
9
|
+
export function matchesPatterns(message: string, patterns: readonly string[]): boolean {
|
|
10
|
+
const lowerMessage = message.toLowerCase();
|
|
11
|
+
return patterns.some((pattern) => lowerMessage.includes(pattern));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getStatusCode(error: unknown): number | undefined {
|
|
15
|
+
if (error && typeof error === "object") {
|
|
16
|
+
const err = error as Record<string, unknown>;
|
|
17
|
+
if (typeof err.status === "number") return err.status;
|
|
18
|
+
if (typeof err.statusCode === "number") return err.statusCode;
|
|
19
|
+
if (err.response && typeof err.response === "object") {
|
|
20
|
+
const resp = err.response as Record<string, unknown>;
|
|
21
|
+
if (typeof resp.status === "number") return resp.status;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function logClassification(info: AIErrorInfo): AIErrorInfo {
|
|
28
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
29
|
+
console.log("[ErrorClassifier] Classified as:", {
|
|
30
|
+
type: info.type,
|
|
31
|
+
messageKey: info.messageKey,
|
|
32
|
+
retryable: info.retryable,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return info;
|
|
36
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Validation Utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
MAX_PROMPT_LENGTH,
|
|
7
|
+
MIN_PROMPT_LENGTH,
|
|
8
|
+
MAX_URL_LENGTH,
|
|
9
|
+
MIN_VIDEO_DURATION_SECONDS,
|
|
10
|
+
MAX_VIDEO_DURATION_SECONDS,
|
|
11
|
+
} from "../constants/validation.constants";
|
|
12
|
+
import type { ValidationResult } from "./validation-types";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Validates text prompt length
|
|
16
|
+
*/
|
|
17
|
+
export function validatePrompt(prompt: string): ValidationResult {
|
|
18
|
+
if (!prompt || typeof prompt !== "string") {
|
|
19
|
+
return { isValid: false, error: "Prompt is required" };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (prompt.length < MIN_PROMPT_LENGTH) {
|
|
23
|
+
return { isValid: false, error: "Prompt is too short" };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (prompt.length > MAX_PROMPT_LENGTH) {
|
|
27
|
+
return { isValid: false, error: "Prompt is too long" };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return { isValid: true };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Validates URL format
|
|
35
|
+
*/
|
|
36
|
+
export function validateUrl(url: string): ValidationResult {
|
|
37
|
+
if (!url || typeof url !== "string") {
|
|
38
|
+
return { isValid: false, error: "URL is required" };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (url.length > MAX_URL_LENGTH) {
|
|
42
|
+
return { isValid: false, error: "URL is too long" };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
new URL(url);
|
|
47
|
+
return { isValid: true };
|
|
48
|
+
} catch {
|
|
49
|
+
return { isValid: false, error: "Invalid URL format" };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validates video duration
|
|
55
|
+
*/
|
|
56
|
+
export function validateVideoDuration(duration: number): ValidationResult {
|
|
57
|
+
if (typeof duration !== "number" || isNaN(duration)) {
|
|
58
|
+
return { isValid: false, error: "Duration must be a number" };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (duration < MIN_VIDEO_DURATION_SECONDS) {
|
|
62
|
+
return {
|
|
63
|
+
isValid: false,
|
|
64
|
+
error: `Duration must be at least ${MIN_VIDEO_DURATION_SECONDS} seconds`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (duration > MAX_VIDEO_DURATION_SECONDS) {
|
|
69
|
+
return {
|
|
70
|
+
isValid: false,
|
|
71
|
+
error: `Duration must not exceed ${MAX_VIDEO_DURATION_SECONDS} seconds`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { isValid: true };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Validates email format
|
|
80
|
+
*/
|
|
81
|
+
export function validateEmail(email: string): ValidationResult {
|
|
82
|
+
if (!email || typeof email !== "string") {
|
|
83
|
+
return { isValid: false, error: "Email is required" };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
87
|
+
if (!emailRegex.test(email)) {
|
|
88
|
+
return { isValid: false, error: "Invalid email format" };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { isValid: true };
|
|
92
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain-Specific Type Guards
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { hasProperty, isObject } from "./structure-guards";
|
|
6
|
+
import { isNonEmptyString } from "./primitive-guards";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Type guard for creation objects with output property
|
|
10
|
+
*/
|
|
11
|
+
export function isCreationWithOutput(
|
|
12
|
+
value: unknown
|
|
13
|
+
): value is { output: unknown } {
|
|
14
|
+
return hasProperty(value, "output") && isObject(value.output);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Type guard for wizard data with id property
|
|
19
|
+
*/
|
|
20
|
+
export function isWizardData(value: unknown): value is { id: string } {
|
|
21
|
+
return hasProperty(value, "id") && isNonEmptyString(value.id);
|
|
22
|
+
}
|