@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
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complex Structure Type Guards
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { isObject, isArray, isNonEmptyString, isNumber, isFunction } from "./primitive-guards";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checks if value is a plain object (not null, not array)
|
|
9
|
+
*/
|
|
10
|
+
export function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
11
|
+
return isObject(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Checks if value is a string URL
|
|
16
|
+
*/
|
|
17
|
+
export function isUrl(value: unknown): value is string {
|
|
18
|
+
if (!isNonEmptyString(value)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
new URL(value);
|
|
24
|
+
return true;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Checks if value is an array of strings
|
|
32
|
+
*/
|
|
33
|
+
export function isStringArray(value: unknown): value is string[] {
|
|
34
|
+
return isArray(value) && value.every((item) => typeof item === "string");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Checks if value is an array of numbers
|
|
39
|
+
*/
|
|
40
|
+
export function isNumberArray(value: unknown): value is number[] {
|
|
41
|
+
return isArray(value) && value.every(isNumber);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Checks if value has a specific property
|
|
46
|
+
*/
|
|
47
|
+
export function hasProperty<K extends PropertyKey>(
|
|
48
|
+
value: unknown,
|
|
49
|
+
key: K
|
|
50
|
+
): value is Record<K, unknown> {
|
|
51
|
+
return isObject(value) && key in value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Checks if object has all required properties
|
|
56
|
+
*/
|
|
57
|
+
export function hasProperties<K extends PropertyKey>(
|
|
58
|
+
value: unknown,
|
|
59
|
+
keys: K[]
|
|
60
|
+
): value is Record<K, unknown> {
|
|
61
|
+
return isObject(value) && keys.every((key) => key in value);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Checks if value is a promise
|
|
66
|
+
*/
|
|
67
|
+
export function isPromise(value: unknown): value is Promise<unknown> {
|
|
68
|
+
return (
|
|
69
|
+
isObject(value) &&
|
|
70
|
+
"then" in value &&
|
|
71
|
+
isFunction(value.then) &&
|
|
72
|
+
"catch" in value &&
|
|
73
|
+
isFunction(value.catch)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -1,153 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Type Guard Utilities
|
|
2
|
+
* Type Guard Utilities - Barrel Export
|
|
3
3
|
* Provides reusable type guards for common type checking patterns
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Checks if value is a non-empty string
|
|
29
|
-
*/
|
|
30
|
-
export function isNonEmptyString(value: unknown): value is string {
|
|
31
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Checks if value is a number (excluding NaN)
|
|
36
|
-
*/
|
|
37
|
-
export function isNumber(value: unknown): value is number {
|
|
38
|
-
return typeof value === "number" && !isNaN(value);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Checks if value is a positive number
|
|
43
|
-
*/
|
|
44
|
-
export function isPositiveNumber(value: unknown): value is number {
|
|
45
|
-
return isNumber(value) && value > 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Checks if value is a boolean
|
|
50
|
-
*/
|
|
51
|
-
export function isBoolean(value: unknown): value is boolean {
|
|
52
|
-
return typeof value === "boolean";
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Checks if value is a function
|
|
57
|
-
*/
|
|
58
|
-
export function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
|
|
59
|
-
return typeof value === "function";
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Checks if value is a promise
|
|
64
|
-
*/
|
|
65
|
-
export function isPromise(value: unknown): value is Promise<unknown> {
|
|
66
|
-
return (
|
|
67
|
-
isObject(value) &&
|
|
68
|
-
"then" in value &&
|
|
69
|
-
isFunction(value.then) &&
|
|
70
|
-
"catch" in value &&
|
|
71
|
-
isFunction(value.catch)
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Checks if value has a specific property
|
|
77
|
-
*/
|
|
78
|
-
export function hasProperty<K extends PropertyKey>(
|
|
79
|
-
value: unknown,
|
|
80
|
-
key: K
|
|
81
|
-
): value is Record<K, unknown> {
|
|
82
|
-
return isObject(value) && key in value;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Checks if value is a date object
|
|
87
|
-
*/
|
|
88
|
-
export function isDate(value: unknown): value is Date {
|
|
89
|
-
return value instanceof Date && !isNaN(value.getTime());
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Checks if value is defined (not null or undefined)
|
|
94
|
-
*/
|
|
95
|
-
export function isDefined<T>(value: T | null | undefined): value is T {
|
|
96
|
-
return value !== null && value !== undefined;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Checks if value is a string URL
|
|
101
|
-
*/
|
|
102
|
-
export function isUrl(value: unknown): value is string {
|
|
103
|
-
if (!isNonEmptyString(value)) {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
new URL(value);
|
|
109
|
-
return true;
|
|
110
|
-
} catch {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Checks if value is an array of strings
|
|
117
|
-
*/
|
|
118
|
-
export function isStringArray(value: unknown): value is string[] {
|
|
119
|
-
return isArray(value) && value.every((item) => typeof item === "string");
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Checks if value is an array of numbers
|
|
124
|
-
*/
|
|
125
|
-
export function isNumberArray(value: unknown): value is number[] {
|
|
126
|
-
return isArray(value) && value.every(isNumber);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Checks if object has all required properties
|
|
131
|
-
*/
|
|
132
|
-
export function hasProperties<K extends PropertyKey>(
|
|
133
|
-
value: unknown,
|
|
134
|
-
keys: K[]
|
|
135
|
-
): value is Record<K, unknown> {
|
|
136
|
-
return isObject(value) && keys.every((key) => key in value);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Type guard for creation objects with output property
|
|
141
|
-
*/
|
|
142
|
-
export function isCreationWithOutput(
|
|
143
|
-
value: unknown
|
|
144
|
-
): value is { output: unknown } {
|
|
145
|
-
return hasProperty(value, "output") && isObject(value.output);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Type guard for wizard data with id property
|
|
150
|
-
*/
|
|
151
|
-
export function isWizardData(value: unknown): value is { id: string } {
|
|
152
|
-
return hasProperty(value, "id") && isNonEmptyString(value.id);
|
|
153
|
-
}
|
|
6
|
+
export {
|
|
7
|
+
isObject,
|
|
8
|
+
isArray,
|
|
9
|
+
isNonEmptyString,
|
|
10
|
+
isNumber,
|
|
11
|
+
isPositiveNumber,
|
|
12
|
+
isBoolean,
|
|
13
|
+
isFunction,
|
|
14
|
+
isDate,
|
|
15
|
+
isDefined,
|
|
16
|
+
} from "./primitive-guards";
|
|
17
|
+
export {
|
|
18
|
+
isPlainObject,
|
|
19
|
+
isUrl,
|
|
20
|
+
isStringArray,
|
|
21
|
+
isNumberArray,
|
|
22
|
+
hasProperty,
|
|
23
|
+
hasProperties,
|
|
24
|
+
isPromise,
|
|
25
|
+
} from "./structure-guards";
|
|
26
|
+
export { isCreationWithOutput, isWizardData } from "./domain-guards";
|
|
@@ -1,188 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Common Validation Utilities
|
|
2
|
+
* Common Validation Utilities - Barrel Export
|
|
3
3
|
* Reusable validation functions for forms and data
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Validates text prompt length
|
|
23
|
-
*/
|
|
24
|
-
export function validatePrompt(prompt: string): ValidationResult {
|
|
25
|
-
if (!prompt || typeof prompt !== "string") {
|
|
26
|
-
return { isValid: false, error: "Prompt is required" };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (prompt.length < MIN_PROMPT_LENGTH) {
|
|
30
|
-
return { isValid: false, error: "Prompt is too short" };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (prompt.length > MAX_PROMPT_LENGTH) {
|
|
34
|
-
return { isValid: false, error: "Prompt is too long" };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return { isValid: true };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Validates user ID
|
|
42
|
-
*/
|
|
43
|
-
export function validateUserId(userId: string): ValidationResult {
|
|
44
|
-
if (!userId || typeof userId !== "string") {
|
|
45
|
-
return { isValid: false, error: "User ID is required" };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (userId.length > MAX_USER_ID_LENGTH) {
|
|
49
|
-
return { isValid: false, error: "User ID is too long" };
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return { isValid: true };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Validates creation ID
|
|
57
|
-
*/
|
|
58
|
-
export function validateCreationId(creationId: string): ValidationResult {
|
|
59
|
-
if (!creationId || typeof creationId !== "string") {
|
|
60
|
-
return { isValid: false, error: "Creation ID is required" };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (creationId.length > MAX_CREATION_ID_LENGTH) {
|
|
64
|
-
return { isValid: false, error: "Creation ID is too long" };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return { isValid: true };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Validates URL format
|
|
72
|
-
*/
|
|
73
|
-
export function validateUrl(url: string): ValidationResult {
|
|
74
|
-
if (!url || typeof url !== "string") {
|
|
75
|
-
return { isValid: false, error: "URL is required" };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (url.length > MAX_URL_LENGTH) {
|
|
79
|
-
return { isValid: false, error: "URL is too long" };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
new URL(url);
|
|
84
|
-
return { isValid: true };
|
|
85
|
-
} catch {
|
|
86
|
-
return { isValid: false, error: "Invalid URL format" };
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Validates video duration
|
|
92
|
-
*/
|
|
93
|
-
export function validateVideoDuration(duration: number): ValidationResult {
|
|
94
|
-
if (typeof duration !== "number" || isNaN(duration)) {
|
|
95
|
-
return { isValid: false, error: "Duration must be a number" };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (duration < MIN_VIDEO_DURATION_SECONDS) {
|
|
99
|
-
return {
|
|
100
|
-
isValid: false,
|
|
101
|
-
error: `Duration must be at least ${MIN_VIDEO_DURATION_SECONDS} seconds`,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (duration > MAX_VIDEO_DURATION_SECONDS) {
|
|
106
|
-
return {
|
|
107
|
-
isValid: false,
|
|
108
|
-
error: `Duration must not exceed ${MAX_VIDEO_DURATION_SECONDS} seconds`,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return { isValid: true };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Validates email format
|
|
117
|
-
*/
|
|
118
|
-
export function validateEmail(email: string): ValidationResult {
|
|
119
|
-
if (!email || typeof email !== "string") {
|
|
120
|
-
return { isValid: false, error: "Email is required" };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
124
|
-
if (!emailRegex.test(email)) {
|
|
125
|
-
return { isValid: false, error: "Invalid email format" };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return { isValid: true };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Validates that a value is not empty
|
|
133
|
-
*/
|
|
134
|
-
export function validateNotEmpty(value: unknown, fieldName = "Value"): ValidationResult {
|
|
135
|
-
if (value === null || value === undefined) {
|
|
136
|
-
return { isValid: false, error: `${fieldName} is required` };
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (typeof value === "string" && value.trim().length === 0) {
|
|
140
|
-
return { isValid: false, error: `${fieldName} cannot be empty` };
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (Array.isArray(value) && value.length === 0) {
|
|
144
|
-
return { isValid: false, error: `${fieldName} cannot be empty` };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return { isValid: true };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Validates numeric range
|
|
152
|
-
*/
|
|
153
|
-
export function validateNumericRange(
|
|
154
|
-
value: number,
|
|
155
|
-
options: {
|
|
156
|
-
min?: number;
|
|
157
|
-
max?: number;
|
|
158
|
-
fieldName?: string;
|
|
159
|
-
}
|
|
160
|
-
): ValidationResult {
|
|
161
|
-
const { min, max, fieldName = "Value" } = options;
|
|
162
|
-
|
|
163
|
-
if (typeof value !== "number" || isNaN(value)) {
|
|
164
|
-
return { isValid: false, error: `${fieldName} must be a number` };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (min !== undefined && value < min) {
|
|
168
|
-
return { isValid: false, error: `${fieldName} must be at least ${min}` };
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (max !== undefined && value > max) {
|
|
172
|
-
return { isValid: false, error: `${fieldName} must not exceed ${max}` };
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return { isValid: true };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Combines multiple validation results
|
|
180
|
-
*/
|
|
181
|
-
export function combineValidations(...results: ValidationResult[]): ValidationResult {
|
|
182
|
-
for (const result of results) {
|
|
183
|
-
if (!result.isValid) {
|
|
184
|
-
return result;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return { isValid: true };
|
|
188
|
-
}
|
|
6
|
+
export type { ValidationResult } from "./validation-types";
|
|
7
|
+
export { validateUserId, validateCreationId } from "./id-validators";
|
|
8
|
+
export {
|
|
9
|
+
validatePrompt,
|
|
10
|
+
validateUrl,
|
|
11
|
+
validateVideoDuration,
|
|
12
|
+
validateEmail,
|
|
13
|
+
} from "./content-validators";
|
|
14
|
+
export {
|
|
15
|
+
validateNotEmpty,
|
|
16
|
+
validateNumericRange,
|
|
17
|
+
combineValidations,
|
|
18
|
+
} from "./general-validators";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks - Authentication Hooks
|
|
3
|
+
* Authentication-related callback hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
|
|
8
|
+
export interface UseAuthCallbacksParams {
|
|
9
|
+
isAuth: boolean;
|
|
10
|
+
userId: string | null;
|
|
11
|
+
showAuthModal: (callback?: () => void) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface AuthCallbacks {
|
|
15
|
+
isAuthenticated: () => boolean;
|
|
16
|
+
onAuthRequired: () => void;
|
|
17
|
+
onAuthCheck: () => boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Hook for authentication-related callbacks
|
|
22
|
+
*/
|
|
23
|
+
export function useAuthCallbacks(params: UseAuthCallbacksParams): AuthCallbacks {
|
|
24
|
+
const { isAuth, userId, showAuthModal } = params;
|
|
25
|
+
|
|
26
|
+
const isAuthenticated = useCallback(
|
|
27
|
+
(): boolean => isAuth && !!userId,
|
|
28
|
+
[isAuth, userId],
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const onAuthRequired = useCallback(() => {
|
|
32
|
+
showAuthModal();
|
|
33
|
+
}, [showAuthModal]);
|
|
34
|
+
|
|
35
|
+
// Alias for different callback interfaces
|
|
36
|
+
const onAuthCheck = isAuthenticated;
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
isAuthenticated,
|
|
40
|
+
onAuthRequired,
|
|
41
|
+
onAuthCheck,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks - Cost Management Hooks
|
|
3
|
+
* Credit and cost-related callback hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
|
|
8
|
+
export interface UseCostCallbacksParams {
|
|
9
|
+
creditBalance: number;
|
|
10
|
+
creditCostPerUnit: number;
|
|
11
|
+
openPaywall: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CostCallbacks {
|
|
15
|
+
canAfford: (cost: number) => boolean;
|
|
16
|
+
calculateCost: (multiplier?: number, _model?: string | null) => number;
|
|
17
|
+
onCreditsRequired: (cost?: number) => void;
|
|
18
|
+
onCreditCheck: (cost: number) => boolean;
|
|
19
|
+
onShowPaywall: (cost: number) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook for cost and credit management callbacks
|
|
24
|
+
*/
|
|
25
|
+
export function useCostCallbacks(params: UseCostCallbacksParams): CostCallbacks {
|
|
26
|
+
const { creditBalance, creditCostPerUnit, openPaywall } = params;
|
|
27
|
+
|
|
28
|
+
const canAfford = useCallback(
|
|
29
|
+
(cost: number): boolean => creditBalance >= cost,
|
|
30
|
+
[creditBalance],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const calculateCost = useCallback(
|
|
34
|
+
(multiplier = 1, _model?: string | null): number => creditCostPerUnit * multiplier,
|
|
35
|
+
[creditCostPerUnit],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const onCreditsRequired = useCallback(
|
|
39
|
+
(_cost?: number) => {
|
|
40
|
+
openPaywall();
|
|
41
|
+
},
|
|
42
|
+
[openPaywall],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Aliases for different callback interfaces
|
|
46
|
+
const onCreditCheck = canAfford;
|
|
47
|
+
const onShowPaywall = onCreditsRequired;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
canAfford,
|
|
51
|
+
calculateCost,
|
|
52
|
+
onCreditsRequired,
|
|
53
|
+
onCreditCheck,
|
|
54
|
+
onShowPaywall,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks - Execution Hooks
|
|
3
|
+
* Generation execution callback hooks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback } from "react";
|
|
7
|
+
import type { AIFeatureGenerationResult } from "./ai-feature-callbacks.types";
|
|
8
|
+
|
|
9
|
+
export interface UseExecutionCallbackParams<TRequest, TResult> {
|
|
10
|
+
executor: (request: TRequest) => Promise<{
|
|
11
|
+
success: boolean;
|
|
12
|
+
data?: TResult;
|
|
13
|
+
error?: string;
|
|
14
|
+
imageUrl?: string;
|
|
15
|
+
imageUrls?: string[];
|
|
16
|
+
}>;
|
|
17
|
+
deductCredits?: (amount: number) => Promise<void>;
|
|
18
|
+
creditCostPerUnit: number;
|
|
19
|
+
onSuccess?: (result: TResult) => void;
|
|
20
|
+
onError?: (error: string) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ExecutionCallbacks<TRequest> {
|
|
24
|
+
executeGeneration: (request: TRequest) => Promise<AIFeatureGenerationResult>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Hook for generation execution callback
|
|
29
|
+
*/
|
|
30
|
+
export function useExecutionCallback<TRequest = unknown, TResult = unknown>(
|
|
31
|
+
params: UseExecutionCallbackParams<TRequest, TResult>,
|
|
32
|
+
): ExecutionCallbacks<TRequest> {
|
|
33
|
+
const { executor, deductCredits, creditCostPerUnit, onSuccess, onError } = params;
|
|
34
|
+
|
|
35
|
+
const executeGeneration = useCallback(
|
|
36
|
+
async (request: TRequest): Promise<AIFeatureGenerationResult> => {
|
|
37
|
+
try {
|
|
38
|
+
const result = await executor(request);
|
|
39
|
+
|
|
40
|
+
if (result.success && deductCredits) {
|
|
41
|
+
await deductCredits(creditCostPerUnit);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (result.success && result.data) {
|
|
45
|
+
onSuccess?.(result.data);
|
|
46
|
+
} else if (!result.success && result.error) {
|
|
47
|
+
onError?.(result.error);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (result.success) {
|
|
51
|
+
return { success: true, imageUrls: result.imageUrls ?? [] };
|
|
52
|
+
}
|
|
53
|
+
return { success: false, error: result.error ?? "Unknown error" };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
onError?.(message);
|
|
57
|
+
return { success: false, error: message };
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[executor, deductCredits, creditCostPerUnit, onSuccess, onError],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
executeGeneration,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Feature Callbacks Type Definitions
|
|
3
|
+
* Type definitions for universal AI feature callbacks adapter
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configuration for AI feature callbacks hook
|
|
8
|
+
* Generic over TRequest and TResult for type safety
|
|
9
|
+
*/
|
|
10
|
+
export interface AIFeatureCallbacksConfig<TRequest = unknown, TResult = unknown> {
|
|
11
|
+
// App provides reactive state
|
|
12
|
+
userId: string | null;
|
|
13
|
+
isAuthenticated: boolean;
|
|
14
|
+
creditBalance: number;
|
|
15
|
+
|
|
16
|
+
// Cost config
|
|
17
|
+
creditCostPerUnit: number;
|
|
18
|
+
|
|
19
|
+
// Executor - the actual generation function
|
|
20
|
+
executor: (request: TRequest) => Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
data?: TResult;
|
|
23
|
+
error?: string;
|
|
24
|
+
imageUrl?: string;
|
|
25
|
+
imageUrls?: string[];
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
// Actions from app - showAuthModal accepts callback for post-auth resume
|
|
29
|
+
showAuthModal: (callback?: () => void) => void;
|
|
30
|
+
openPaywall: () => void;
|
|
31
|
+
deductCredits?: (amount: number) => Promise<void>;
|
|
32
|
+
|
|
33
|
+
// Optional callbacks
|
|
34
|
+
onSuccess?: (result: TResult) => void;
|
|
35
|
+
onError?: (error: string) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Discriminated union result type for generation
|
|
40
|
+
*/
|
|
41
|
+
export type AIFeatureGenerationResult =
|
|
42
|
+
| { success: true; imageUrls: string[] }
|
|
43
|
+
| { success: false; error: string };
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Universal callbacks interface that maps to all feature-specific ones
|
|
47
|
+
* Compatible with TextToImageCallbacks, ImageToVideoCallbacks, TextToVideoCallbacks
|
|
48
|
+
*/
|
|
49
|
+
export interface AIFeatureCallbacks<TRequest = unknown, TResult = unknown> {
|
|
50
|
+
// User state - needed by orchestrator
|
|
51
|
+
userId: string | null;
|
|
52
|
+
|
|
53
|
+
// TextToImageCallbacks compatible
|
|
54
|
+
executeGeneration: (request: TRequest) => Promise<AIFeatureGenerationResult>;
|
|
55
|
+
calculateCost: (multiplier?: number, _model?: string | null) => number;
|
|
56
|
+
canAfford: (cost: number) => boolean;
|
|
57
|
+
isAuthenticated: () => boolean;
|
|
58
|
+
onAuthRequired: () => void;
|
|
59
|
+
onCreditsRequired: (cost?: number) => void;
|
|
60
|
+
onSuccess?: (result: TResult) => void;
|
|
61
|
+
onError?: (error: string) => void;
|
|
62
|
+
|
|
63
|
+
// ImageToVideoCallbacks compatible
|
|
64
|
+
onCreditCheck: (cost: number) => boolean;
|
|
65
|
+
onShowPaywall: (cost: number) => void;
|
|
66
|
+
|
|
67
|
+
// TextToVideoCallbacks compatible
|
|
68
|
+
onAuthCheck: () => boolean;
|
|
69
|
+
}
|