@umituz/react-native-ai-generation-content 1.37.4 → 1.37.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/domains/scenarios/configs/index.ts +17 -0
- package/src/domains/scenarios/configs/wizard-config-resolver.ts +107 -0
- package/src/domains/scenarios/configs/wizard-input-detector.ts +57 -0
- package/src/domains/scenarios/configs/wizard-input.types.ts +31 -0
- package/src/domains/scenarios/configs/wizard-step-factories.ts +116 -0
- package/src/domains/scenarios/index.ts +2 -7
- package/src/domains/scenarios/configs/wizard-configs.ts +0 -331
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.37.
|
|
3
|
+
"version": "1.37.6",
|
|
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",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard Configs Public API
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { WizardInputType } from "./wizard-input.types";
|
|
6
|
+
export type { WizardConfigOptions, WizardConfigFactory } from "./wizard-input.types";
|
|
7
|
+
|
|
8
|
+
export { detectWizardInputType, SCENARIO_TO_WIZARD_INPUT_MAP } from "./wizard-input-detector";
|
|
9
|
+
|
|
10
|
+
export { CONFIG_FACTORIES, getConfigFactory } from "./wizard-step-factories";
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
getScenarioWizardConfig,
|
|
14
|
+
registerWizardConfig,
|
|
15
|
+
hasExplicitConfig,
|
|
16
|
+
getScenarioWizardInputType,
|
|
17
|
+
} from "./wizard-config-resolver";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard Config Resolver
|
|
3
|
+
* Main resolver for getting wizard configurations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { WizardFeatureConfig } from "../../generation/wizard/domain/entities/wizard-config.types";
|
|
7
|
+
import { getConfiguredScenario } from "../infrastructure/scenario-registry";
|
|
8
|
+
import { WizardInputType, type WizardConfigOptions } from "./wizard-input.types";
|
|
9
|
+
import { detectWizardInputType, SCENARIO_TO_WIZARD_INPUT_MAP } from "./wizard-input-detector";
|
|
10
|
+
import { getConfigFactory } from "./wizard-step-factories";
|
|
11
|
+
|
|
12
|
+
declare const __DEV__: boolean;
|
|
13
|
+
|
|
14
|
+
const scenarioWizardConfigs: Record<string, WizardFeatureConfig> = {};
|
|
15
|
+
|
|
16
|
+
function mergeConfigOverrides(
|
|
17
|
+
config: WizardFeatureConfig,
|
|
18
|
+
overrides?: Partial<WizardFeatureConfig>,
|
|
19
|
+
): WizardFeatureConfig {
|
|
20
|
+
if (!overrides) return config;
|
|
21
|
+
return {
|
|
22
|
+
...config,
|
|
23
|
+
...overrides,
|
|
24
|
+
steps: overrides.steps ?? config.steps,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function applyAdditionalSteps(
|
|
29
|
+
config: WizardFeatureConfig,
|
|
30
|
+
additionalSteps?: WizardFeatureConfig["steps"],
|
|
31
|
+
): WizardFeatureConfig {
|
|
32
|
+
if (!additionalSteps) return config;
|
|
33
|
+
return { ...config, steps: [...config.steps, ...additionalSteps] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function buildConfig(
|
|
37
|
+
scenarioId: string,
|
|
38
|
+
inputType: WizardInputType,
|
|
39
|
+
options?: WizardConfigOptions,
|
|
40
|
+
): WizardFeatureConfig {
|
|
41
|
+
const factory = getConfigFactory(inputType);
|
|
42
|
+
let config = factory(scenarioId);
|
|
43
|
+
config = mergeConfigOverrides(config, options?.overrides);
|
|
44
|
+
return applyAdditionalSteps(config, options?.additionalSteps);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get wizard config for a scenario
|
|
49
|
+
* Priority: 1. Explicit inputType 2. Registry config 3. Scenario inputType 4. Pattern detection
|
|
50
|
+
*/
|
|
51
|
+
export function getScenarioWizardConfig(
|
|
52
|
+
scenarioId: string,
|
|
53
|
+
options?: WizardConfigOptions,
|
|
54
|
+
): WizardFeatureConfig {
|
|
55
|
+
if (options?.inputType) {
|
|
56
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
57
|
+
console.log("[WizardConfig] Using explicit inputType", { scenarioId, inputType: options.inputType });
|
|
58
|
+
}
|
|
59
|
+
return buildConfig(scenarioId, options.inputType, options);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (scenarioWizardConfigs[scenarioId]) {
|
|
63
|
+
let config = scenarioWizardConfigs[scenarioId];
|
|
64
|
+
config = mergeConfigOverrides(config, options?.overrides);
|
|
65
|
+
return applyAdditionalSteps(config, options?.additionalSteps);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const scenario = getConfiguredScenario(scenarioId);
|
|
69
|
+
if (scenario?.inputType) {
|
|
70
|
+
const wizardInputType = SCENARIO_TO_WIZARD_INPUT_MAP[scenario.inputType];
|
|
71
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
72
|
+
console.log("[WizardConfig] Using scenario.inputType", {
|
|
73
|
+
scenarioId,
|
|
74
|
+
scenarioInputType: scenario.inputType,
|
|
75
|
+
wizardInputType,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return buildConfig(scenarioId, wizardInputType, options);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const inputType = detectWizardInputType(scenarioId);
|
|
82
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
83
|
+
console.log("[WizardConfig] Auto-detected inputType", { scenarioId, inputType });
|
|
84
|
+
}
|
|
85
|
+
return buildConfig(scenarioId, inputType, options);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register a custom wizard config
|
|
90
|
+
*/
|
|
91
|
+
export function registerWizardConfig(scenarioId: string, config: WizardFeatureConfig): void {
|
|
92
|
+
scenarioWizardConfigs[scenarioId] = config;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if scenario has explicit wizard config
|
|
97
|
+
*/
|
|
98
|
+
export function hasExplicitConfig(scenarioId: string): boolean {
|
|
99
|
+
return scenarioId in scenarioWizardConfigs;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get input type for a scenario
|
|
104
|
+
*/
|
|
105
|
+
export function getScenarioWizardInputType(scenarioId: string): WizardInputType {
|
|
106
|
+
return detectWizardInputType(scenarioId);
|
|
107
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard Input Detector
|
|
3
|
+
* Detects wizard input type from scenario ID patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ScenarioInputType } from "../domain/Scenario";
|
|
7
|
+
import { WizardInputType } from "./wizard-input.types";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Map ScenarioInputType to WizardInputType
|
|
11
|
+
*/
|
|
12
|
+
export const SCENARIO_TO_WIZARD_INPUT_MAP: Record<ScenarioInputType, WizardInputType> = {
|
|
13
|
+
single: WizardInputType.SINGLE_IMAGE,
|
|
14
|
+
dual: WizardInputType.DUAL_IMAGE,
|
|
15
|
+
text: WizardInputType.TEXT_INPUT,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Pattern-based input detection
|
|
20
|
+
* Only matches generic I/O patterns
|
|
21
|
+
*/
|
|
22
|
+
const INPUT_PATTERNS: Record<WizardInputType, readonly RegExp[]> = {
|
|
23
|
+
[WizardInputType.DUAL_IMAGE]: [/ai-kiss/i, /ai-hug/i, /couple/i, /dual/i],
|
|
24
|
+
[WizardInputType.SINGLE_IMAGE]: [
|
|
25
|
+
/^image-to-video$/i,
|
|
26
|
+
/upscale/i,
|
|
27
|
+
/restore/i,
|
|
28
|
+
/enhance/i,
|
|
29
|
+
/remove-background/i,
|
|
30
|
+
/background-remove/i,
|
|
31
|
+
/remove-object/i,
|
|
32
|
+
/hd-touch/i,
|
|
33
|
+
/anime-selfie/i,
|
|
34
|
+
],
|
|
35
|
+
[WizardInputType.TEXT_INPUT]: [/^text-to-video$/i, /^text-to-image$/i, /prompt-to/i],
|
|
36
|
+
[WizardInputType.DUAL_IMAGE_FACE]: [/face-swap/i, /swap-face/i],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const DETECTION_ORDER: readonly WizardInputType[] = [
|
|
40
|
+
WizardInputType.TEXT_INPUT,
|
|
41
|
+
WizardInputType.DUAL_IMAGE,
|
|
42
|
+
WizardInputType.DUAL_IMAGE_FACE,
|
|
43
|
+
WizardInputType.SINGLE_IMAGE,
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Detect input type from scenario ID using pattern matching
|
|
48
|
+
*/
|
|
49
|
+
export function detectWizardInputType(scenarioId: string): WizardInputType {
|
|
50
|
+
for (const type of DETECTION_ORDER) {
|
|
51
|
+
const patterns = INPUT_PATTERNS[type];
|
|
52
|
+
if (patterns.some((pattern) => pattern.test(scenarioId))) {
|
|
53
|
+
return type;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return WizardInputType.SINGLE_IMAGE;
|
|
57
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard Input Types
|
|
3
|
+
* Type definitions for wizard input classification
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { WizardFeatureConfig } from "../../generation/wizard/domain/entities/wizard-config.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Input Type Classification
|
|
10
|
+
* Based on what inputs the wizard needs (photos, text)
|
|
11
|
+
*/
|
|
12
|
+
export enum WizardInputType {
|
|
13
|
+
DUAL_IMAGE = "dual_image",
|
|
14
|
+
SINGLE_IMAGE = "single_image",
|
|
15
|
+
TEXT_INPUT = "text_input",
|
|
16
|
+
DUAL_IMAGE_FACE = "dual_image_face",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Configuration Options for wizard config resolver
|
|
21
|
+
*/
|
|
22
|
+
export interface WizardConfigOptions {
|
|
23
|
+
readonly inputType?: WizardInputType;
|
|
24
|
+
readonly additionalSteps?: WizardFeatureConfig["steps"];
|
|
25
|
+
readonly overrides?: Partial<WizardFeatureConfig>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Factory function type for creating wizard configs
|
|
30
|
+
*/
|
|
31
|
+
export type WizardConfigFactory = (scenarioId: string) => WizardFeatureConfig;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard Step Factories
|
|
3
|
+
* Factory functions for creating wizard step configurations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { WizardFeatureConfig } from "../../generation/wizard/domain/entities/wizard-config.types";
|
|
7
|
+
import { WizardInputType, type WizardConfigFactory } from "./wizard-input.types";
|
|
8
|
+
|
|
9
|
+
function createDualImageConfig(scenarioId: string): WizardFeatureConfig {
|
|
10
|
+
return {
|
|
11
|
+
id: scenarioId,
|
|
12
|
+
name: scenarioId,
|
|
13
|
+
steps: [
|
|
14
|
+
{
|
|
15
|
+
id: "photo_1",
|
|
16
|
+
type: "photo_upload",
|
|
17
|
+
titleKey: "photoUpload.first.title",
|
|
18
|
+
subtitleKey: "photoUpload.first.subtitle",
|
|
19
|
+
showFaceDetection: true,
|
|
20
|
+
showPhotoTips: true,
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "photo_2",
|
|
25
|
+
type: "photo_upload",
|
|
26
|
+
titleKey: "photoUpload.second.title",
|
|
27
|
+
subtitleKey: "photoUpload.second.subtitle",
|
|
28
|
+
showFaceDetection: true,
|
|
29
|
+
showPhotoTips: true,
|
|
30
|
+
required: true,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function createSingleImageConfig(scenarioId: string): WizardFeatureConfig {
|
|
37
|
+
return {
|
|
38
|
+
id: scenarioId,
|
|
39
|
+
name: scenarioId,
|
|
40
|
+
steps: [
|
|
41
|
+
{
|
|
42
|
+
id: "photo_1",
|
|
43
|
+
type: "photo_upload",
|
|
44
|
+
titleKey: "photoUpload.single.title",
|
|
45
|
+
subtitleKey: "photoUpload.single.subtitle",
|
|
46
|
+
showFaceDetection: false,
|
|
47
|
+
showPhotoTips: true,
|
|
48
|
+
required: true,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function createTextInputConfig(scenarioId: string): WizardFeatureConfig {
|
|
55
|
+
return {
|
|
56
|
+
id: scenarioId,
|
|
57
|
+
name: scenarioId,
|
|
58
|
+
steps: [
|
|
59
|
+
{
|
|
60
|
+
id: "text_input",
|
|
61
|
+
type: "text_input",
|
|
62
|
+
titleKey: "textInput.title",
|
|
63
|
+
subtitleKey: "textInput.subtitle",
|
|
64
|
+
placeholderKey: "textInput.placeholder",
|
|
65
|
+
minLength: 10,
|
|
66
|
+
maxLength: 500,
|
|
67
|
+
multiline: true,
|
|
68
|
+
required: true,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function createDualImageFaceConfig(scenarioId: string): WizardFeatureConfig {
|
|
75
|
+
return {
|
|
76
|
+
id: scenarioId,
|
|
77
|
+
name: scenarioId,
|
|
78
|
+
steps: [
|
|
79
|
+
{
|
|
80
|
+
id: "photo_1",
|
|
81
|
+
type: "photo_upload",
|
|
82
|
+
titleKey: "photoUpload.source.title",
|
|
83
|
+
subtitleKey: "photoUpload.source.subtitle",
|
|
84
|
+
showFaceDetection: true,
|
|
85
|
+
showPhotoTips: true,
|
|
86
|
+
required: true,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "photo_2",
|
|
90
|
+
type: "photo_upload",
|
|
91
|
+
titleKey: "photoUpload.target.title",
|
|
92
|
+
subtitleKey: "photoUpload.target.subtitle",
|
|
93
|
+
showFaceDetection: false,
|
|
94
|
+
showPhotoTips: true,
|
|
95
|
+
required: true,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Registry of config factories by input type
|
|
103
|
+
*/
|
|
104
|
+
export const CONFIG_FACTORIES: Record<WizardInputType, WizardConfigFactory> = {
|
|
105
|
+
[WizardInputType.DUAL_IMAGE]: createDualImageConfig,
|
|
106
|
+
[WizardInputType.SINGLE_IMAGE]: createSingleImageConfig,
|
|
107
|
+
[WizardInputType.TEXT_INPUT]: createTextInputConfig,
|
|
108
|
+
[WizardInputType.DUAL_IMAGE_FACE]: createDualImageFaceConfig,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get factory for a specific input type
|
|
113
|
+
*/
|
|
114
|
+
export function getConfigFactory(inputType: WizardInputType): WizardConfigFactory {
|
|
115
|
+
return CONFIG_FACTORIES[inputType];
|
|
116
|
+
}
|
|
@@ -37,19 +37,14 @@ export { createStoryTemplate } from "./infrastructure/utils/scenario-utils";
|
|
|
37
37
|
// Wizard Configurations - App-agnostic, classifies by INPUT REQUIREMENTS
|
|
38
38
|
export {
|
|
39
39
|
WizardInputType,
|
|
40
|
-
SCENARIO_WIZARD_CONFIGS,
|
|
41
40
|
detectWizardInputType,
|
|
42
41
|
getScenarioWizardConfig,
|
|
43
42
|
hasExplicitConfig,
|
|
44
43
|
getScenarioWizardInputType,
|
|
45
44
|
registerWizardConfig,
|
|
46
|
-
|
|
47
|
-
FeatureType,
|
|
48
|
-
detectFeatureType,
|
|
49
|
-
getScenarioFeatureType,
|
|
50
|
-
} from "./configs/wizard-configs";
|
|
45
|
+
} from "./configs";
|
|
51
46
|
|
|
52
|
-
export type { WizardConfigOptions } from "./configs
|
|
47
|
+
export type { WizardConfigOptions } from "./configs";
|
|
53
48
|
|
|
54
49
|
// Presentation - Containers
|
|
55
50
|
export { CategoryNavigationContainer } from "./presentation/containers";
|
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wizard Configurations - App-Agnostic
|
|
3
|
-
* Classifies features by INPUT REQUIREMENTS, not app-specific scenarios
|
|
4
|
-
* Apps can override inputType or provide custom step configurations
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { WizardFeatureConfig } from "../../generation/wizard/domain/entities/wizard-config.types";
|
|
8
|
-
|
|
9
|
-
declare const __DEV__: boolean;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Input Type Classification
|
|
13
|
-
* Based on what inputs the wizard needs (photos, text)
|
|
14
|
-
* NOT based on app-specific scenario names
|
|
15
|
-
*/
|
|
16
|
-
export enum WizardInputType {
|
|
17
|
-
/** Two images required (any two-person/two-image scenario) */
|
|
18
|
-
DUAL_IMAGE = "dual_image",
|
|
19
|
-
/** Single image required */
|
|
20
|
-
SINGLE_IMAGE = "single_image",
|
|
21
|
-
/** Text input only, no images */
|
|
22
|
-
TEXT_INPUT = "text_input",
|
|
23
|
-
/** Two images with face detection (face swap scenarios) */
|
|
24
|
-
DUAL_IMAGE_FACE = "dual_image_face",
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** @deprecated Use WizardInputType instead */
|
|
28
|
-
export const FeatureType = WizardInputType;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Generic Input Detection Patterns
|
|
32
|
-
* Only patterns that describe input/output, NOT app-specific scenarios
|
|
33
|
-
*/
|
|
34
|
-
const INPUT_PATTERNS: Record<WizardInputType, RegExp[]> = {
|
|
35
|
-
[WizardInputType.DUAL_IMAGE]: [
|
|
36
|
-
/ai-kiss/i,
|
|
37
|
-
/ai-hug/i,
|
|
38
|
-
/couple/i,
|
|
39
|
-
/dual/i,
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
[WizardInputType.SINGLE_IMAGE]: [
|
|
43
|
-
/^image-to-video$/i,
|
|
44
|
-
/upscale/i,
|
|
45
|
-
/restore/i,
|
|
46
|
-
/enhance/i,
|
|
47
|
-
/remove-background/i,
|
|
48
|
-
/background-remove/i,
|
|
49
|
-
/remove-object/i,
|
|
50
|
-
/hd-touch/i,
|
|
51
|
-
/anime-selfie/i,
|
|
52
|
-
],
|
|
53
|
-
|
|
54
|
-
[WizardInputType.TEXT_INPUT]: [
|
|
55
|
-
/^text-to-video$/i,
|
|
56
|
-
/^text-to-image$/i,
|
|
57
|
-
/prompt-to/i,
|
|
58
|
-
],
|
|
59
|
-
|
|
60
|
-
[WizardInputType.DUAL_IMAGE_FACE]: [
|
|
61
|
-
/face-swap/i,
|
|
62
|
-
/swap-face/i,
|
|
63
|
-
],
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Detect input type from scenario ID
|
|
68
|
-
* Only matches generic I/O patterns
|
|
69
|
-
* Returns SINGLE_IMAGE as safe default
|
|
70
|
-
*/
|
|
71
|
-
export const detectWizardInputType = (scenarioId: string): WizardInputType => {
|
|
72
|
-
// Check patterns in priority order: TEXT_INPUT, DUAL_IMAGE, DUAL_IMAGE_FACE, SINGLE_IMAGE
|
|
73
|
-
const checkOrder: WizardInputType[] = [
|
|
74
|
-
WizardInputType.TEXT_INPUT,
|
|
75
|
-
WizardInputType.DUAL_IMAGE,
|
|
76
|
-
WizardInputType.DUAL_IMAGE_FACE,
|
|
77
|
-
WizardInputType.SINGLE_IMAGE,
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
for (const type of checkOrder) {
|
|
81
|
-
const patterns = INPUT_PATTERNS[type];
|
|
82
|
-
if (patterns.some((pattern) => pattern.test(scenarioId))) {
|
|
83
|
-
return type;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Safe default: SINGLE_IMAGE (most common use case)
|
|
88
|
-
return WizardInputType.SINGLE_IMAGE;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Config Factory: DUAL_IMAGE (2 photos required)
|
|
93
|
-
* Generic labels - apps provide translations
|
|
94
|
-
*/
|
|
95
|
-
const createDualImageConfig = (scenarioId: string): WizardFeatureConfig => ({
|
|
96
|
-
id: scenarioId,
|
|
97
|
-
name: scenarioId,
|
|
98
|
-
steps: [
|
|
99
|
-
{
|
|
100
|
-
id: "photo_1",
|
|
101
|
-
type: "photo_upload",
|
|
102
|
-
titleKey: "photoUpload.first.title",
|
|
103
|
-
subtitleKey: "photoUpload.first.subtitle",
|
|
104
|
-
showFaceDetection: true,
|
|
105
|
-
showPhotoTips: true,
|
|
106
|
-
required: true,
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
id: "photo_2",
|
|
110
|
-
type: "photo_upload",
|
|
111
|
-
titleKey: "photoUpload.second.title",
|
|
112
|
-
subtitleKey: "photoUpload.second.subtitle",
|
|
113
|
-
showFaceDetection: true,
|
|
114
|
-
showPhotoTips: true,
|
|
115
|
-
required: true,
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Config Factory: SINGLE_IMAGE (1 photo required)
|
|
122
|
-
*/
|
|
123
|
-
const createSingleImageConfig = (scenarioId: string): WizardFeatureConfig => ({
|
|
124
|
-
id: scenarioId,
|
|
125
|
-
name: scenarioId,
|
|
126
|
-
steps: [
|
|
127
|
-
{
|
|
128
|
-
id: "photo_1",
|
|
129
|
-
type: "photo_upload",
|
|
130
|
-
titleKey: "photoUpload.single.title",
|
|
131
|
-
subtitleKey: "photoUpload.single.subtitle",
|
|
132
|
-
showFaceDetection: false,
|
|
133
|
-
showPhotoTips: true,
|
|
134
|
-
required: true,
|
|
135
|
-
},
|
|
136
|
-
],
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Config Factory: TEXT_INPUT (text only, no photos)
|
|
141
|
-
*/
|
|
142
|
-
const createTextInputConfig = (scenarioId: string): WizardFeatureConfig => ({
|
|
143
|
-
id: scenarioId,
|
|
144
|
-
name: scenarioId,
|
|
145
|
-
steps: [
|
|
146
|
-
{
|
|
147
|
-
id: "text_input",
|
|
148
|
-
type: "text_input",
|
|
149
|
-
titleKey: "textInput.title",
|
|
150
|
-
subtitleKey: "textInput.subtitle",
|
|
151
|
-
placeholderKey: "textInput.placeholder",
|
|
152
|
-
minLength: 10,
|
|
153
|
-
maxLength: 500,
|
|
154
|
-
multiline: true,
|
|
155
|
-
required: true,
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Config Factory: DUAL_IMAGE_FACE (2 photos with face detection)
|
|
162
|
-
*/
|
|
163
|
-
const createDualImageFaceConfig = (scenarioId: string): WizardFeatureConfig => ({
|
|
164
|
-
id: scenarioId,
|
|
165
|
-
name: scenarioId,
|
|
166
|
-
steps: [
|
|
167
|
-
{
|
|
168
|
-
id: "photo_1",
|
|
169
|
-
type: "photo_upload",
|
|
170
|
-
titleKey: "photoUpload.source.title",
|
|
171
|
-
subtitleKey: "photoUpload.source.subtitle",
|
|
172
|
-
showFaceDetection: true,
|
|
173
|
-
showPhotoTips: true,
|
|
174
|
-
required: true,
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
id: "photo_2",
|
|
178
|
-
type: "photo_upload",
|
|
179
|
-
titleKey: "photoUpload.target.title",
|
|
180
|
-
subtitleKey: "photoUpload.target.subtitle",
|
|
181
|
-
showFaceDetection: false,
|
|
182
|
-
showPhotoTips: true,
|
|
183
|
-
required: true,
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Config Factories Registry
|
|
190
|
-
*/
|
|
191
|
-
const CONFIG_FACTORIES: Record<WizardInputType, (id: string) => WizardFeatureConfig> = {
|
|
192
|
-
[WizardInputType.DUAL_IMAGE]: createDualImageConfig,
|
|
193
|
-
[WizardInputType.SINGLE_IMAGE]: createSingleImageConfig,
|
|
194
|
-
[WizardInputType.TEXT_INPUT]: createTextInputConfig,
|
|
195
|
-
[WizardInputType.DUAL_IMAGE_FACE]: createDualImageFaceConfig,
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Explicit Wizard Configs (Optional)
|
|
200
|
-
* Apps can register custom configs for specific scenario IDs
|
|
201
|
-
*/
|
|
202
|
-
export const SCENARIO_WIZARD_CONFIGS: Record<string, WizardFeatureConfig> = {};
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Merge config with overrides
|
|
206
|
-
*/
|
|
207
|
-
const mergeConfigOverrides = (
|
|
208
|
-
config: WizardFeatureConfig,
|
|
209
|
-
overrides?: Partial<WizardFeatureConfig>,
|
|
210
|
-
): WizardFeatureConfig => {
|
|
211
|
-
if (!overrides) return config;
|
|
212
|
-
return {
|
|
213
|
-
...config,
|
|
214
|
-
...overrides,
|
|
215
|
-
steps: overrides.steps || config.steps,
|
|
216
|
-
};
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Configuration Options
|
|
221
|
-
*/
|
|
222
|
-
export interface WizardConfigOptions {
|
|
223
|
-
/** Explicit input type - highest priority */
|
|
224
|
-
readonly inputType?: WizardInputType;
|
|
225
|
-
/** Additional steps to append */
|
|
226
|
-
readonly additionalSteps?: WizardFeatureConfig["steps"];
|
|
227
|
-
/** Custom overrides */
|
|
228
|
-
readonly overrides?: Partial<WizardFeatureConfig>;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Get wizard config for a scenario
|
|
233
|
-
*
|
|
234
|
-
* Priority:
|
|
235
|
-
* 1. Explicit inputType in options (highest)
|
|
236
|
-
* 2. Explicit config in SCENARIO_WIZARD_CONFIGS
|
|
237
|
-
* 3. Auto-detect from scenario ID patterns
|
|
238
|
-
*
|
|
239
|
-
* @example
|
|
240
|
-
* // Auto-detect from ID
|
|
241
|
-
* getScenarioWizardConfig("text-to-video")
|
|
242
|
-
*
|
|
243
|
-
* // Explicit input type for app-specific scenarios
|
|
244
|
-
* getScenarioWizardConfig("ai-kiss", { inputType: WizardInputType.DUAL_IMAGE })
|
|
245
|
-
*/
|
|
246
|
-
export const getScenarioWizardConfig = (
|
|
247
|
-
scenarioId: string,
|
|
248
|
-
options?: WizardConfigOptions,
|
|
249
|
-
): WizardFeatureConfig => {
|
|
250
|
-
// 1. Explicit inputType (highest priority)
|
|
251
|
-
if (options?.inputType) {
|
|
252
|
-
const factory = CONFIG_FACTORIES[options.inputType];
|
|
253
|
-
let config = factory(scenarioId);
|
|
254
|
-
config = mergeConfigOverrides(config, options.overrides);
|
|
255
|
-
|
|
256
|
-
if (options.additionalSteps) {
|
|
257
|
-
config = { ...config, steps: [...config.steps, ...options.additionalSteps] };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
261
|
-
console.log("[WizardConfig] Using explicit inputType", {
|
|
262
|
-
scenarioId,
|
|
263
|
-
inputType: options.inputType,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return config;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// 2. Explicit config in registry
|
|
271
|
-
if (SCENARIO_WIZARD_CONFIGS[scenarioId]) {
|
|
272
|
-
let config = SCENARIO_WIZARD_CONFIGS[scenarioId];
|
|
273
|
-
config = mergeConfigOverrides(config, options?.overrides);
|
|
274
|
-
|
|
275
|
-
if (options?.additionalSteps) {
|
|
276
|
-
config = { ...config, steps: [...config.steps, ...options.additionalSteps] };
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return config;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// 3. Auto-detect from scenario ID
|
|
283
|
-
const inputType = detectWizardInputType(scenarioId);
|
|
284
|
-
|
|
285
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
286
|
-
console.log("[WizardConfig] Auto-detected inputType", {
|
|
287
|
-
scenarioId,
|
|
288
|
-
inputType,
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const factory = CONFIG_FACTORIES[inputType];
|
|
293
|
-
let config = factory(scenarioId);
|
|
294
|
-
config = mergeConfigOverrides(config, options?.overrides);
|
|
295
|
-
|
|
296
|
-
if (options?.additionalSteps) {
|
|
297
|
-
config = { ...config, steps: [...config.steps, ...options.additionalSteps] };
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return config;
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Register a custom wizard config for a scenario
|
|
305
|
-
*/
|
|
306
|
-
export const registerWizardConfig = (
|
|
307
|
-
scenarioId: string,
|
|
308
|
-
config: WizardFeatureConfig,
|
|
309
|
-
): void => {
|
|
310
|
-
SCENARIO_WIZARD_CONFIGS[scenarioId] = config;
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Check if scenario has explicit wizard config
|
|
315
|
-
*/
|
|
316
|
-
export const hasExplicitConfig = (scenarioId: string): boolean => {
|
|
317
|
-
return scenarioId in SCENARIO_WIZARD_CONFIGS;
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Get input type for a scenario
|
|
322
|
-
*/
|
|
323
|
-
export const getScenarioWizardInputType = (scenarioId: string): WizardInputType => {
|
|
324
|
-
return detectWizardInputType(scenarioId);
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
/** @deprecated Use getScenarioWizardInputType instead */
|
|
328
|
-
export const getScenarioFeatureType = getScenarioWizardInputType;
|
|
329
|
-
|
|
330
|
-
/** @deprecated Use detectWizardInputType instead */
|
|
331
|
-
export const detectFeatureType = detectWizardInputType;
|