@umituz/react-native-ai-generation-content 1.24.2 → 1.25.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.24.2",
3
+ "version": "1.25.0",
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",
@@ -1,16 +1,93 @@
1
1
  /**
2
2
  * Wizard Configurations for ALL Scenarios
3
- * Each scenario defines its wizard flow here
4
- * NO feature-specific code - just configs!
3
+ * Auto-detects feature type and generates appropriate config
4
+ * Supports overrides for customization
5
5
  */
6
6
 
7
7
  import type { WizardFeatureConfig } from "../../wizard/domain/entities/wizard-config.types";
8
8
 
9
9
  /**
10
- * COUPLE SCENARIOS - 2 Photo Uploads
11
- * romantic-kiss, ai-hug, couple-future, couple-ai-baby, etc.
10
+ * Feature Type Classification
11
+ * Determines wizard flow based on scenario characteristics
12
12
  */
13
- const createCoupleWizardConfig = (scenarioId: string): WizardFeatureConfig => ({
13
+ export enum FeatureType {
14
+ COUPLE = "couple", // 2 photos - romantic/partner scenarios
15
+ SINGLE_PHOTO = "single_photo", // 1 photo - editing/transformation
16
+ FACE_SWAP = "face_swap", // 2 photos - face replacement
17
+ TEXT_BASED = "text_based", // 0 photos - text-to-media
18
+ }
19
+
20
+ /**
21
+ * Feature Detection Patterns
22
+ * Regex patterns to auto-detect feature type from scenario ID
23
+ */
24
+ const FEATURE_PATTERNS: Record<FeatureType, RegExp[]> = {
25
+ [FeatureType.COUPLE]: [
26
+ /kiss/i, // romantic-kiss, ai-kiss, first-kiss, etc.
27
+ /hug/i, // ai-hug, back-hug, bear-hug, etc.
28
+ /couple/i, // couple-future, couple-ai-baby
29
+ /partner/i, // partner scenarios
30
+ /wedding/i, // wedding scenarios
31
+ /anniversary/i,
32
+ /dance/i, // first-dance, etc.
33
+ /together/i,
34
+ /embrace/i,
35
+ /romance/i,
36
+ /love/i,
37
+ /relationship/i,
38
+ /years/i, // 5-years, 10-years (couple-future)
39
+ /age/i, // old-age (couple-future)
40
+ /future.*child/i, // future-child
41
+ /parenthood/i,
42
+ /proposal/i,
43
+ /engagement/i,
44
+ ],
45
+
46
+ [FeatureType.SINGLE_PHOTO]: [
47
+ /background.*remove/i,
48
+ /remove.*background/i,
49
+ /photo.*restore/i,
50
+ /restore.*photo/i,
51
+ /upscale/i,
52
+ /hd.*touch/i,
53
+ /touch.*up/i,
54
+ /enhance/i,
55
+ /anime.*selfie/i,
56
+ /selfie.*anime/i,
57
+ /image.*to.*video/i,
58
+ /remove.*object/i,
59
+ /object.*remove/i,
60
+ ],
61
+
62
+ [FeatureType.TEXT_BASED]: [
63
+ /text.*to.*video/i,
64
+ /text.*to.*image/i,
65
+ /prompt.*to/i,
66
+ ],
67
+
68
+ [FeatureType.FACE_SWAP]: [
69
+ /face.*swap/i,
70
+ /swap.*face/i,
71
+ ],
72
+ };
73
+
74
+ /**
75
+ * Detect feature type from scenario ID
76
+ */
77
+ export const detectFeatureType = (scenarioId: string): FeatureType => {
78
+ for (const [type, patterns] of Object.entries(FEATURE_PATTERNS)) {
79
+ if (patterns.some((pattern) => pattern.test(scenarioId))) {
80
+ return type as FeatureType;
81
+ }
82
+ }
83
+ // Default: COUPLE (most common in AI video generation apps)
84
+ return FeatureType.COUPLE;
85
+ };
86
+
87
+ /**
88
+ * Config Factory for COUPLE features (2 photos)
89
+ */
90
+ const createCoupleConfig = (scenarioId: string): WizardFeatureConfig => ({
14
91
  id: scenarioId,
15
92
  name: scenarioId,
16
93
  steps: [
@@ -18,8 +95,8 @@ const createCoupleWizardConfig = (scenarioId: string): WizardFeatureConfig => ({
18
95
  id: "photo_a",
19
96
  type: "photo_upload",
20
97
  label: "First Partner",
21
- titleKey: `${scenarioId}.partnerA.title`,
22
- subtitleKey: `${scenarioId}.partnerA.subtitle`,
98
+ titleKey: "photoUpload.step1.title",
99
+ subtitleKey: "photoUpload.step1.subtitle",
23
100
  showFaceDetection: true,
24
101
  showPhotoTips: true,
25
102
  required: true,
@@ -28,8 +105,8 @@ const createCoupleWizardConfig = (scenarioId: string): WizardFeatureConfig => ({
28
105
  id: "photo_b",
29
106
  type: "photo_upload",
30
107
  label: "Second Partner",
31
- titleKey: `${scenarioId}.partnerB.title`,
32
- subtitleKey: `${scenarioId}.partnerB.subtitle`,
108
+ titleKey: "photoUpload.step2.title",
109
+ subtitleKey: "photoUpload.step2.subtitle",
33
110
  showFaceDetection: true,
34
111
  showPhotoTips: true,
35
112
  required: true,
@@ -38,79 +115,38 @@ const createCoupleWizardConfig = (scenarioId: string): WizardFeatureConfig => ({
38
115
  });
39
116
 
40
117
  /**
41
- * SINGLE PHOTO SCENARIOS
42
- * image-to-video, face-swap (source), etc.
118
+ * Config Factory for SINGLE_PHOTO features (1 photo)
43
119
  */
44
- const createSinglePhotoWizardConfig = (
45
- scenarioId: string,
46
- options?: {
47
- requireStyle?: boolean;
48
- requireDuration?: boolean;
49
- },
50
- ): WizardFeatureConfig => {
51
- const steps: WizardFeatureConfig["steps"] = [
120
+ const createSinglePhotoConfig = (scenarioId: string): WizardFeatureConfig => ({
121
+ id: scenarioId,
122
+ name: scenarioId,
123
+ steps: [
52
124
  {
53
125
  id: "photo",
54
126
  type: "photo_upload",
55
127
  label: "Your Photo",
56
- titleKey: `${scenarioId}.photo.title`,
57
- subtitleKey: `${scenarioId}.photo.subtitle`,
128
+ titleKey: "photoUpload.single.title",
129
+ subtitleKey: "photoUpload.single.subtitle",
58
130
  showFaceDetection: false,
59
131
  showPhotoTips: true,
60
132
  required: true,
61
133
  },
62
- ];
63
-
64
- // Add style selection if needed
65
- if (options?.requireStyle) {
66
- steps.push({
67
- id: "style_selection",
68
- type: "selection",
69
- selectionType: "style",
70
- titleKey: `${scenarioId}.style.title`,
71
- subtitleKey: `${scenarioId}.style.subtitle`,
72
- options: [], // Filled by feature
73
- required: true,
74
- });
75
- }
76
-
77
- // Add duration selection if needed
78
- if (options?.requireDuration) {
79
- steps.push({
80
- id: "duration_selection",
81
- type: "selection",
82
- selectionType: "duration",
83
- titleKey: `${scenarioId}.duration.title`,
84
- subtitleKey: `${scenarioId}.duration.subtitle`,
85
- options: [
86
- { id: "5s", label: "5 seconds", value: 5 },
87
- { id: "10s", label: "10 seconds", value: 10 },
88
- { id: "15s", label: "15 seconds", value: 15 },
89
- ],
90
- required: true,
91
- });
92
- }
93
-
94
- return {
95
- id: scenarioId,
96
- name: scenarioId,
97
- steps,
98
- };
99
- };
134
+ ],
135
+ });
100
136
 
101
137
  /**
102
- * TEXT-TO-VIDEO SCENARIOS
138
+ * Config Factory for TEXT_BASED features (0 photos, text input)
103
139
  */
104
- const createTextToVideoWizardConfig = (scenarioId: string): WizardFeatureConfig => ({
140
+ const createTextBasedConfig = (scenarioId: string): WizardFeatureConfig => ({
105
141
  id: scenarioId,
106
142
  name: scenarioId,
107
143
  steps: [
108
144
  {
109
145
  id: "text_input",
110
146
  type: "text_input",
111
- titleKey: `${scenarioId}.prompt.title`,
112
- subtitleKey: `${scenarioId}.prompt.subtitle`,
113
- placeholderKey: `${scenarioId}.prompt.placeholder`,
147
+ titleKey: "textInput.title",
148
+ subtitleKey: "textInput.subtitle",
149
+ placeholderKey: "textInput.placeholder",
114
150
  minLength: 10,
115
151
  maxLength: 500,
116
152
  multiline: true,
@@ -120,68 +156,129 @@ const createTextToVideoWizardConfig = (scenarioId: string): WizardFeatureConfig
120
156
  id: "style_selection",
121
157
  type: "selection",
122
158
  selectionType: "style",
123
- titleKey: `${scenarioId}.style.title`,
124
- options: [], // Filled by feature
159
+ titleKey: "styleSelection.title",
160
+ subtitleKey: "styleSelection.subtitle",
161
+ options: [], // Provided by app/feature
162
+ required: false,
163
+ },
164
+ ],
165
+ });
166
+
167
+ /**
168
+ * Config Factory for FACE_SWAP features (2 photos, different context)
169
+ */
170
+ const createFaceSwapConfig = (scenarioId: string): WizardFeatureConfig => ({
171
+ id: scenarioId,
172
+ name: scenarioId,
173
+ steps: [
174
+ {
175
+ id: "source_photo",
176
+ type: "photo_upload",
177
+ label: "Source Face",
178
+ titleKey: "faceSwap.source.title",
179
+ subtitleKey: "faceSwap.source.subtitle",
180
+ showFaceDetection: true,
181
+ showPhotoTips: true,
125
182
  required: true,
126
183
  },
127
184
  {
128
- id: "duration_selection",
129
- type: "selection",
130
- selectionType: "duration",
131
- titleKey: `${scenarioId}.duration.title`,
132
- options: [
133
- { id: "5s", label: "5 seconds", value: 5 },
134
- { id: "10s", label: "10 seconds", value: 10 },
135
- ],
185
+ id: "target_photo",
186
+ type: "photo_upload",
187
+ label: "Target Photo",
188
+ titleKey: "faceSwap.target.title",
189
+ subtitleKey: "faceSwap.target.subtitle",
190
+ showFaceDetection: false,
191
+ showPhotoTips: true,
136
192
  required: true,
137
193
  },
138
194
  ],
139
195
  });
140
196
 
141
197
  /**
142
- * SCENARIO WIZARD CONFIG REGISTRY
143
- * Maps scenario ID to wizard config
198
+ * Config Factories Registry
199
+ */
200
+ const FEATURE_CONFIG_FACTORIES: Record<FeatureType, (id: string) => WizardFeatureConfig> = {
201
+ [FeatureType.COUPLE]: createCoupleConfig,
202
+ [FeatureType.SINGLE_PHOTO]: createSinglePhotoConfig,
203
+ [FeatureType.TEXT_BASED]: createTextBasedConfig,
204
+ [FeatureType.FACE_SWAP]: createFaceSwapConfig,
205
+ };
206
+
207
+ /**
208
+ * Explicit Wizard Configs (Optional)
209
+ * Define specific configs for scenarios that need custom flows
210
+ * Most scenarios will use auto-generated configs from factories
144
211
  */
145
212
  export const SCENARIO_WIZARD_CONFIGS: Record<string, WizardFeatureConfig> = {
146
- // COUPLE SCENARIOS (2 photos)
147
- "romantic-kiss": createCoupleWizardConfig("romantic-kiss"),
148
- "ai-hug": createCoupleWizardConfig("ai-hug"),
149
- "couple-future-40": createCoupleWizardConfig("couple-future-40"),
150
- "couple-future-50": createCoupleWizardConfig("couple-future-50"),
151
- "couple-future-60": createCoupleWizardConfig("couple-future-60"),
152
- "couple-future-70": createCoupleWizardConfig("couple-future-70"),
153
- "couple-future-80": createCoupleWizardConfig("couple-future-80"),
154
- "couple-ai-baby": createCoupleWizardConfig("couple-ai-baby"),
155
-
156
- // SINGLE PHOTO SCENARIOS
157
- "image-to-video": createSinglePhotoWizardConfig("image-to-video", {
158
- requireStyle: true,
159
- requireDuration: true,
160
- }),
161
- "face-swap": createSinglePhotoWizardConfig("face-swap"),
162
- "anime-selfie": createSinglePhotoWizardConfig("anime-selfie"),
163
-
164
- // TEXT-TO-VIDEO SCENARIOS
165
- "text-to-video": createTextToVideoWizardConfig("text-to-video"),
213
+ // Add custom configs here only if needed
214
+ // Example:
215
+ // "special-scenario": {
216
+ // id: "special-scenario",
217
+ // steps: [...custom steps]
218
+ // }
219
+ };
220
+
221
+ /**
222
+ * Merge config overrides
223
+ */
224
+ const mergeConfigOverrides = (
225
+ config: WizardFeatureConfig,
226
+ overrides?: Partial<WizardFeatureConfig>,
227
+ ): WizardFeatureConfig => {
228
+ if (!overrides) return config;
229
+
230
+ return {
231
+ ...config,
232
+ ...overrides,
233
+ steps: overrides.steps || config.steps,
234
+ };
166
235
  };
167
236
 
168
237
  /**
169
238
  * Get wizard config for a scenario
239
+ * 1. Check for explicit config in SCENARIO_WIZARD_CONFIGS
240
+ * 2. Auto-detect feature type and generate config
241
+ * 3. Apply overrides if provided
242
+ *
243
+ * This means ALL scenarios work automatically!
170
244
  */
171
- export const getScenarioWizardConfig = (scenarioId: string): WizardFeatureConfig | null => {
172
- return SCENARIO_WIZARD_CONFIGS[scenarioId] || null;
245
+ export const getScenarioWizardConfig = (
246
+ scenarioId: string,
247
+ overrides?: Partial<WizardFeatureConfig>,
248
+ ): WizardFeatureConfig => {
249
+ // 1. Explicit config (highest priority)
250
+ if (SCENARIO_WIZARD_CONFIGS[scenarioId]) {
251
+ return mergeConfigOverrides(SCENARIO_WIZARD_CONFIGS[scenarioId], overrides);
252
+ }
253
+
254
+ // 2. Auto-detect feature type
255
+ const featureType = detectFeatureType(scenarioId);
256
+
257
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
258
+ console.log("[WizardConfig] Auto-detected feature type", {
259
+ scenarioId,
260
+ featureType,
261
+ });
262
+ }
263
+
264
+ // 3. Generate config from factory
265
+ const factory = FEATURE_CONFIG_FACTORIES[featureType];
266
+ const config = factory(scenarioId);
267
+
268
+ // 4. Apply overrides
269
+ return mergeConfigOverrides(config, overrides);
173
270
  };
174
271
 
175
272
  /**
176
- * Check if scenario has wizard config
273
+ * Check if scenario has explicit wizard config
177
274
  */
178
- export const hasWizardConfig = (scenarioId: string): boolean => {
275
+ export const hasExplicitConfig = (scenarioId: string): boolean => {
179
276
  return scenarioId in SCENARIO_WIZARD_CONFIGS;
180
277
  };
181
278
 
182
279
  /**
183
- * Get all scenario IDs with wizard configs
280
+ * Get feature type for a scenario
184
281
  */
185
- export const getConfiguredScenarioIds = (): string[] => {
186
- return Object.keys(SCENARIO_WIZARD_CONFIGS);
282
+ export const getScenarioFeatureType = (scenarioId: string): FeatureType => {
283
+ return detectFeatureType(scenarioId);
187
284
  };
@@ -14,10 +14,12 @@ export { SCENARIOS } from "./infrastructure/ScenariosData";
14
14
  // Utils
15
15
  export { createStoryTemplate } from "./infrastructure/utils/scenario-utils";
16
16
 
17
- // Wizard Configurations - Each scenario's wizard flow
17
+ // Wizard Configurations - Auto-detects feature type and generates config
18
18
  export {
19
+ FeatureType,
19
20
  SCENARIO_WIZARD_CONFIGS,
21
+ detectFeatureType,
20
22
  getScenarioWizardConfig,
21
- hasWizardConfig,
22
- getConfiguredScenarioIds,
23
+ hasExplicitConfig,
24
+ getScenarioFeatureType,
23
25
  } from "./configs/wizard-configs";