ugcinc 4.0.2 → 4.1.1

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.
Files changed (161) hide show
  1. package/dist/accounts.d.ts +146 -1
  2. package/dist/automations/index.d.ts +174 -0
  3. package/dist/automations/index.js +194 -0
  4. package/dist/automations/nodes/account.d.ts +6 -0
  5. package/dist/automations/nodes/account.js +28 -0
  6. package/dist/automations/nodes/auto-caption.d.ts +23 -0
  7. package/dist/automations/nodes/auto-caption.js +49 -0
  8. package/dist/automations/nodes/auto-post.d.ts +22 -0
  9. package/dist/automations/nodes/auto-post.js +52 -0
  10. package/dist/automations/nodes/branch.d.ts +21 -0
  11. package/dist/automations/nodes/branch.js +46 -0
  12. package/dist/automations/nodes/collect.d.ts +7 -0
  13. package/dist/automations/nodes/collect.js +51 -0
  14. package/dist/automations/nodes/compose-workflow.d.ts +8 -0
  15. package/dist/automations/nodes/compose-workflow.js +61 -0
  16. package/dist/automations/nodes/create-dm.d.ts +35 -0
  17. package/dist/automations/nodes/create-dm.js +86 -0
  18. package/dist/automations/nodes/custom-model.d.ts +18 -0
  19. package/dist/automations/nodes/custom-model.js +52 -0
  20. package/dist/automations/nodes/deduplicate.d.ts +7 -0
  21. package/dist/automations/nodes/deduplicate.js +36 -0
  22. package/dist/automations/nodes/destructure.d.ts +25 -0
  23. package/dist/automations/nodes/destructure.js +65 -0
  24. package/dist/automations/nodes/for-each.d.ts +22 -0
  25. package/dist/automations/nodes/for-each.js +84 -0
  26. package/dist/automations/nodes/generate-image.d.ts +15 -0
  27. package/dist/automations/nodes/generate-image.js +45 -0
  28. package/dist/automations/nodes/generate-video.d.ts +15 -0
  29. package/dist/automations/nodes/generate-video.js +45 -0
  30. package/dist/automations/nodes/if.d.ts +21 -0
  31. package/dist/automations/nodes/if.js +44 -0
  32. package/dist/automations/nodes/image-composer.d.ts +46 -0
  33. package/dist/automations/nodes/image-composer.js +135 -0
  34. package/dist/automations/nodes/index.d.ts +312 -0
  35. package/dist/automations/nodes/index.js +92 -0
  36. package/dist/automations/nodes/internal.d.ts +8 -0
  37. package/dist/automations/nodes/internal.js +10 -0
  38. package/dist/automations/nodes/llm.d.ts +26 -0
  39. package/dist/automations/nodes/llm.js +85 -0
  40. package/dist/automations/nodes/manual-trigger.d.ts +14 -0
  41. package/dist/automations/nodes/manual-trigger.js +32 -0
  42. package/dist/automations/nodes/media.d.ts +13 -0
  43. package/dist/automations/nodes/media.js +40 -0
  44. package/dist/automations/nodes/not.d.ts +5 -0
  45. package/dist/automations/nodes/not.js +35 -0
  46. package/dist/automations/nodes/output.d.ts +16 -0
  47. package/dist/automations/nodes/output.js +32 -0
  48. package/dist/automations/nodes/random-route.d.ts +24 -0
  49. package/dist/automations/nodes/random-route.js +53 -0
  50. package/dist/automations/nodes/random.d.ts +16 -0
  51. package/dist/automations/nodes/random.js +50 -0
  52. package/dist/automations/nodes/recurrence.d.ts +29 -0
  53. package/dist/automations/nodes/recurrence.js +50 -0
  54. package/dist/automations/nodes/save-to-media.d.ts +15 -0
  55. package/dist/automations/nodes/save-to-media.js +31 -0
  56. package/dist/automations/nodes/screenshot-animation.d.ts +6 -0
  57. package/dist/automations/nodes/screenshot-animation.js +36 -0
  58. package/dist/automations/nodes/social-audio.d.ts +7 -0
  59. package/dist/automations/nodes/social-audio.js +30 -0
  60. package/dist/automations/nodes/text.d.ts +6 -0
  61. package/dist/automations/nodes/text.js +41 -0
  62. package/dist/automations/nodes/transcript.d.ts +5 -0
  63. package/dist/automations/nodes/transcript.js +46 -0
  64. package/dist/automations/nodes/types.d.ts +202 -0
  65. package/dist/automations/nodes/types.js +22 -0
  66. package/dist/automations/nodes/video-composer.d.ts +16 -0
  67. package/dist/automations/nodes/video-composer.js +117 -0
  68. package/dist/automations/nodes/video-import.d.ts +9 -0
  69. package/dist/automations/nodes/video-import.js +23 -0
  70. package/dist/automations/types.d.ts +431 -0
  71. package/dist/automations/types.js +29 -0
  72. package/dist/automations.d.ts +5 -33
  73. package/dist/automations.js +6 -647
  74. package/dist/comments.d.ts +26 -1
  75. package/dist/comments.js +3 -0
  76. package/dist/graph-controller.d.ts +211 -0
  77. package/dist/graph-controller.js +656 -0
  78. package/dist/index.d.ts +22 -9
  79. package/dist/index.js +47 -24
  80. package/dist/internal-utils.d.ts +8 -0
  81. package/dist/internal-utils.js +22 -0
  82. package/dist/media.d.ts +135 -1
  83. package/dist/nodes/account.d.ts +7 -0
  84. package/dist/nodes/account.js +29 -0
  85. package/dist/nodes/auto-caption.d.ts +17 -0
  86. package/dist/nodes/auto-caption.js +46 -0
  87. package/dist/nodes/auto-post.d.ts +21 -0
  88. package/dist/nodes/auto-post.js +54 -0
  89. package/dist/nodes/branch.d.ts +12 -0
  90. package/dist/nodes/branch.js +50 -0
  91. package/dist/nodes/collect.d.ts +6 -0
  92. package/dist/nodes/collect.js +56 -0
  93. package/dist/nodes/compose-workflow.d.ts +21 -0
  94. package/dist/nodes/compose-workflow.js +42 -0
  95. package/dist/nodes/create-dm.d.ts +40 -0
  96. package/dist/nodes/create-dm.js +88 -0
  97. package/dist/nodes/custom-model.d.ts +19 -0
  98. package/dist/nodes/custom-model.js +52 -0
  99. package/dist/nodes/deduplicate.d.ts +8 -0
  100. package/dist/nodes/deduplicate.js +36 -0
  101. package/dist/nodes/destructure.d.ts +25 -0
  102. package/dist/nodes/destructure.js +65 -0
  103. package/dist/nodes/for-each.d.ts +23 -0
  104. package/dist/nodes/for-each.js +84 -0
  105. package/dist/nodes/generate-image.d.ts +16 -0
  106. package/dist/nodes/generate-image.js +45 -0
  107. package/dist/nodes/generate-video.d.ts +16 -0
  108. package/dist/nodes/generate-video.js +45 -0
  109. package/dist/nodes/if.d.ts +22 -0
  110. package/dist/nodes/if.js +44 -0
  111. package/dist/nodes/image-composer.d.ts +14 -0
  112. package/dist/nodes/image-composer.js +95 -0
  113. package/dist/nodes/index.d.ts +20 -0
  114. package/dist/nodes/index.js +93 -0
  115. package/dist/nodes/llm.d.ts +27 -0
  116. package/dist/nodes/llm.js +85 -0
  117. package/dist/nodes/manual-trigger.d.ts +16 -0
  118. package/dist/nodes/manual-trigger.js +32 -0
  119. package/dist/nodes/media.d.ts +17 -0
  120. package/dist/nodes/media.js +40 -0
  121. package/dist/nodes/not.d.ts +6 -0
  122. package/dist/nodes/not.js +35 -0
  123. package/dist/nodes/output.d.ts +9 -0
  124. package/dist/nodes/output.js +32 -0
  125. package/dist/nodes/random-route.d.ts +3 -0
  126. package/dist/nodes/random-route.js +50 -0
  127. package/dist/nodes/random.d.ts +3 -0
  128. package/dist/nodes/random.js +48 -0
  129. package/dist/nodes/recurrence.d.ts +3 -0
  130. package/dist/nodes/recurrence.js +45 -0
  131. package/dist/nodes/save-to-media.d.ts +3 -0
  132. package/dist/nodes/save-to-media.js +26 -0
  133. package/dist/nodes/screenshot-animation.d.ts +7 -0
  134. package/dist/nodes/screenshot-animation.js +36 -0
  135. package/dist/nodes/social-audio.d.ts +3 -0
  136. package/dist/nodes/social-audio.js +26 -0
  137. package/dist/nodes/text.d.ts +3 -0
  138. package/dist/nodes/text.js +38 -0
  139. package/dist/nodes/transcript.d.ts +3 -0
  140. package/dist/nodes/transcript.js +42 -0
  141. package/dist/nodes/types.d.ts +146 -0
  142. package/dist/nodes/types.js +22 -0
  143. package/dist/nodes/video-composer.d.ts +3 -0
  144. package/dist/nodes/video-composer.js +67 -0
  145. package/dist/nodes/video-import.d.ts +3 -0
  146. package/dist/nodes/video-import.js +35 -0
  147. package/dist/org.d.ts +13 -1
  148. package/dist/ports.js +3 -9
  149. package/dist/posts.d.ts +88 -1
  150. package/dist/render/compositions/IMessageDmComposition/types.d.ts +24 -24
  151. package/dist/render/compositions/ImageEditorComposition.js +2 -8
  152. package/dist/render/compositions/VideoEditorComposition.js +2 -24
  153. package/dist/render/types/element.d.ts +0 -33
  154. package/dist/render/types/index.d.ts +1 -1
  155. package/dist/render/types/video.d.ts +2 -2
  156. package/dist/render.d.ts +2 -1
  157. package/dist/stats.d.ts +128 -1
  158. package/dist/tasks.d.ts +20 -1
  159. package/dist/types.d.ts +1 -2216
  160. package/dist/types.js +2 -124
  161. package/package.json +1 -1
package/dist/types.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { ImageEditorElement, ImageEditorNodeConfig, DimensionPresetKey, VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, VideoEditorImageSequenceSegment, VideoEditorVideoSequenceSegment, TimeValue, TimeMode, SegmentTimelinePosition, DeduplicationInput } from './render/types';
2
1
  /**
3
- * API response types
2
+ * API Response Types
4
3
  */
5
4
  export interface SuccessResponse<T> {
6
5
  code: 200;
@@ -15,2217 +14,3 @@ export interface ErrorResponse {
15
14
  data?: never;
16
15
  }
17
16
  export type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
18
- /**
19
- * Account types
20
- */
21
- export interface Account {
22
- id: string;
23
- org_id: string;
24
- type: string;
25
- tag: string | null;
26
- org_group: string | null;
27
- user_group: string | null;
28
- username: string | null;
29
- nick_name: string | null;
30
- pfp_url: string | null;
31
- bio: string | null;
32
- warmup_enabled: boolean | null;
33
- warmup_version: 'original' | 'v1_smart' | 'v2_smart' | null;
34
- post_version: 'original' | 'v1_custom' | null;
35
- description: string | null;
36
- keywords: string | null;
37
- profiles: string | null;
38
- niches: string | null;
39
- age_range: string | null;
40
- sex: string | null;
41
- status: 'uninitialized' | 'pending' | 'initialized' | 'setup' | 'warming' | 'warmed' | 'needs_replacement' | 'error' | 'failed' | 'deleted';
42
- phone_type: 'physical_iphone' | 'physical_android' | 'emulated_android' | 'social_api' | null;
43
- oneup_social_network_id?: string | null;
44
- oneup_category_id?: string | null;
45
- metadata?: {
46
- pending_info_change?: {
47
- nick_name?: string;
48
- pfp_url?: string;
49
- bio?: string;
50
- requested_at?: string;
51
- };
52
- failure_reason?: string;
53
- error_type?: 'needs_replacement' | 'change_account';
54
- [key: string]: unknown;
55
- } | null;
56
- }
57
- export interface AccountStat {
58
- id: string;
59
- account_id: string;
60
- followers: number | null;
61
- following: number | null;
62
- views: number | null;
63
- likes: number | null;
64
- created_at: string;
65
- }
66
- export interface AccountTask {
67
- id: string;
68
- account_id: string;
69
- type: string;
70
- status: string;
71
- scheduled_time: string | null;
72
- edit_profile_info: EditProfileInfo | null;
73
- created_at: string;
74
- }
75
- export interface EditProfileInfo {
76
- avatarUrl?: string;
77
- nickName?: string;
78
- bio?: string;
79
- }
80
- /**
81
- * Task types
82
- */
83
- export type TaskType = 'warmup_scroll' | 'warmup_search_term' | 'warmup_search_profile' | 'edit_profile' | 'update_posts';
84
- export interface Task {
85
- id: string;
86
- account_id: string;
87
- type: TaskType;
88
- status: string;
89
- scheduled_time: string | null;
90
- duration: number | null;
91
- keywords: string | null;
92
- edit_profile_info: EditProfileInfo | null;
93
- created_at: string;
94
- }
95
- /**
96
- * Post types
97
- */
98
- export type PostType = 'video' | 'slideshow';
99
- export type PostStatus = 'scheduled' | 'pending' | 'complete' | 'failed' | 'retrying' | 'deleting' | 'deleted' | 'hidden' | 'require-approval';
100
- export interface Post {
101
- id: string;
102
- account_id: string;
103
- type: PostType;
104
- status: PostStatus;
105
- social_id: string | null;
106
- caption: string | null;
107
- title: string | null;
108
- media_urls: string[] | null;
109
- music_post_id: string | null;
110
- social_audio_id: string | null;
111
- scheduled_at: string | null;
112
- postUrl?: string;
113
- }
114
- export interface PostStat {
115
- id: string;
116
- post_id: string;
117
- views: number | null;
118
- likes: number | null;
119
- comments: number | null;
120
- shares: number | null;
121
- saves: number | null;
122
- created_at: string;
123
- }
124
- /**
125
- * Request parameter types
126
- */
127
- export interface GetAccountsParams {
128
- tag?: string;
129
- org_group?: string;
130
- user_group?: string;
131
- status?: 'uninitialized' | 'pending' | 'initialized' | 'setup' | 'warming' | 'warmed' | 'needs_replacement' | 'error' | 'failed' | 'deleted';
132
- }
133
- export interface GetAccountStatsParams {
134
- accountIds?: string[];
135
- startDate?: string;
136
- endDate?: string;
137
- tag?: string;
138
- org_group?: string;
139
- user_group?: string;
140
- }
141
- export interface GetAccountStatusParams {
142
- accountIds?: string[];
143
- includeCompleted?: boolean;
144
- }
145
- /**
146
- * Individual account info update for bulk operations
147
- */
148
- export interface AccountInfoUpdate {
149
- accountId: string;
150
- tag?: string;
151
- org_group?: string;
152
- user_group?: string;
153
- keywords?: string;
154
- profiles?: string;
155
- description?: string;
156
- warmupVersion?: 'original' | 'v1_smart' | 'v2_smart';
157
- postVersion?: 'original' | 'v1_custom';
158
- phoneType?: 'physical_iphone' | 'physical_android' | 'emulated_android' | 'social_api';
159
- }
160
- /**
161
- * Parameters for updating account info (bulk)
162
- */
163
- export interface UpdateAccountInfoParams {
164
- updates: AccountInfoUpdate[];
165
- }
166
- /**
167
- * Result for individual account info update
168
- */
169
- export interface AccountInfoUpdateResult {
170
- accountId: string;
171
- success: boolean;
172
- account?: Account;
173
- error?: string;
174
- }
175
- /**
176
- * Response for bulk account info updates
177
- */
178
- export interface UpdateAccountInfoResponse {
179
- message: string;
180
- successful: number;
181
- failed: number;
182
- results: AccountInfoUpdateResult[];
183
- }
184
- /**
185
- * Individual account social update for bulk operations
186
- */
187
- export interface AccountSocialUpdate {
188
- accountId: string;
189
- avatarUrl?: string;
190
- nickName?: string;
191
- bio?: string;
192
- }
193
- /**
194
- * Parameters for updating account social profile (bulk)
195
- */
196
- export interface UpdateAccountSocialParams {
197
- updates: AccountSocialUpdate[];
198
- }
199
- /**
200
- * Result for individual account social update
201
- */
202
- export interface AccountSocialUpdateResult {
203
- accountId: string;
204
- success: boolean;
205
- error?: string;
206
- }
207
- /**
208
- * Response for bulk account social updates
209
- */
210
- export interface UpdateAccountSocialResponse {
211
- message: string;
212
- successful: number;
213
- failed: number;
214
- results: AccountSocialUpdateResult[];
215
- }
216
- export interface DeleteAccountPostsParams {
217
- accountIds: string[];
218
- }
219
- export interface DeleteAccountPostsResponse {
220
- message: string;
221
- successful: number;
222
- failed: number;
223
- errors?: Array<{
224
- accountId: string;
225
- error: string;
226
- }>;
227
- }
228
- export interface ResetWarmupParams {
229
- accountId: string;
230
- delete_activity?: boolean;
231
- }
232
- export interface ResetWarmupResponse {
233
- message: string;
234
- tasks_affected: number;
235
- action: 'deleted' | 'reset';
236
- }
237
- export interface GetTasksParams {
238
- accountIds?: string[];
239
- startDate?: string;
240
- endDate?: string;
241
- taskType?: TaskType;
242
- }
243
- export interface GetPostsParams {
244
- accountIds?: string[];
245
- postIds?: string[];
246
- startDate?: string;
247
- endDate?: string;
248
- }
249
- export interface CreateSlideshowParams {
250
- accountId: string | null;
251
- caption?: string;
252
- title?: string;
253
- socialAudioId?: string;
254
- postTime?: string;
255
- imageUrls: string[];
256
- strict?: boolean;
257
- tag?: string;
258
- user_group?: string;
259
- org_group?: string;
260
- }
261
- export interface GetPostStatsParams {
262
- postIds?: string[];
263
- startDate?: string;
264
- endDate?: string;
265
- }
266
- export interface GetPostStatusParams {
267
- postId: string;
268
- }
269
- export interface CreateVideoParams {
270
- accountId: string | null;
271
- caption?: string;
272
- socialAudioId?: string;
273
- postTime?: string;
274
- videoUrl: string;
275
- strict?: boolean;
276
- tag?: string;
277
- user_group?: string;
278
- org_group?: string;
279
- }
280
- export interface DeletePostsParams {
281
- postIds: string[];
282
- }
283
- export interface DeletePostsResponse {
284
- deleted: number;
285
- deleting: number;
286
- deletedIds: string[];
287
- deletingIds: string[];
288
- errors?: Array<{
289
- postId: string;
290
- error: string;
291
- }>;
292
- }
293
- export interface RetryPostsParams {
294
- postIds: string[];
295
- }
296
- export interface SetPostStatusParams {
297
- postIds: string[];
298
- status: string;
299
- }
300
- export interface SetPostStatusResponse {
301
- updated: number;
302
- ids: string[];
303
- }
304
- export interface RefreshStatsParams {
305
- org_group?: string;
306
- }
307
- export interface RefreshStatsError {
308
- accountId: string;
309
- username: string;
310
- error: string;
311
- }
312
- export interface RefreshStatsResponse {
313
- accounts_refreshed: number;
314
- accounts_failed: number;
315
- total_accounts: number;
316
- account_stats: AccountStat[];
317
- post_stats: PostStat[];
318
- post_stats_count: number;
319
- errors?: RefreshStatsError[];
320
- }
321
- export interface DailyAggregatedStat {
322
- date: Date | string;
323
- followers: number;
324
- following: number;
325
- views: number;
326
- likes: number;
327
- posts: number;
328
- }
329
- export interface GetDailyAggregatedStatsParams {
330
- startDate: string;
331
- endDate: string;
332
- accountIds?: string[];
333
- tag?: string;
334
- org_group?: string;
335
- user_group?: string;
336
- }
337
- export interface DailyAccountStat {
338
- date: Date | string;
339
- account_id: string;
340
- followers: number;
341
- following: number;
342
- views: number;
343
- likes: number;
344
- }
345
- export interface GetDailyAccountStatsParams {
346
- startDate: string;
347
- endDate: string;
348
- accountIds?: string[];
349
- tag?: string;
350
- org_group?: string;
351
- user_group?: string;
352
- }
353
- export interface DailyPostStat {
354
- date: Date | string;
355
- post_id: string;
356
- account_id: string;
357
- caption: string | null;
358
- media_urls: string[] | null;
359
- social_id: string | null;
360
- account_username: string | null;
361
- account_type: string;
362
- views: number;
363
- likes: number;
364
- comments: number;
365
- shares: number;
366
- saves: number;
367
- views_change: number;
368
- likes_change: number;
369
- comments_change: number;
370
- shares_change: number;
371
- saves_change: number;
372
- }
373
- export interface GetDailyPostStatsParams {
374
- startDate: string;
375
- endDate: string;
376
- accountIds?: string[];
377
- tag?: string;
378
- org_group?: string;
379
- user_group?: string;
380
- }
381
- export interface TopAccount {
382
- account_id: string;
383
- username: string | null;
384
- nick_name: string | null;
385
- pfp_url: string | null;
386
- type: string;
387
- tag: string | null;
388
- followers: number | null;
389
- following: number | null;
390
- views: number | null;
391
- likes: number | null;
392
- created_at: string;
393
- }
394
- export interface GetTopAccountsParams {
395
- metric: 'followers' | 'following' | 'views' | 'likes';
396
- limit?: number;
397
- accountIds?: string[];
398
- tag?: string;
399
- org_group?: string;
400
- user_group?: string;
401
- }
402
- export interface TopPost {
403
- post_id: string;
404
- account_id: string;
405
- caption: string | null;
406
- media_urls: string[] | null;
407
- type: string;
408
- social_id: string | null;
409
- views: number | null;
410
- likes: number | null;
411
- comments: number | null;
412
- shares: number | null;
413
- saves: number | null;
414
- created_at: string;
415
- }
416
- export interface GetTopPostsParams {
417
- metric: 'views' | 'likes' | 'comments' | 'shares' | 'saves';
418
- limit?: number;
419
- postIds?: string[];
420
- }
421
- /**
422
- * Organization and API Key types
423
- */
424
- export interface ApiKey {
425
- id: string;
426
- name: string;
427
- created_at: string;
428
- }
429
- export interface DeleteApiKeyParams {
430
- apiKeyId: string;
431
- }
432
- export interface EditApiKeyParams {
433
- apiKeyId: string;
434
- name: string;
435
- }
436
- /**
437
- * Render types
438
- */
439
- interface BaseEditorConfig {
440
- width: number;
441
- height: number;
442
- fps: number;
443
- duration: number;
444
- }
445
- export type { VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, VideoEditorImageSequenceSegment, VideoEditorVideoSequenceSegment, TimeValue, TimeMode, SegmentTimelinePosition, DeduplicationInput };
446
- export interface CropBoundary {
447
- elementId?: string;
448
- inputRef?: string;
449
- }
450
- export interface CropAxisConfig {
451
- enabled: boolean;
452
- mode: 'all-elements' | 'between-elements';
453
- startBoundary?: CropBoundary;
454
- endBoundary?: CropBoundary;
455
- paddingStart?: number;
456
- paddingEnd?: number;
457
- minSize?: number;
458
- }
459
- export interface DynamicCropConfig {
460
- vertical?: CropAxisConfig;
461
- horizontal?: CropAxisConfig;
462
- }
463
- export type { ImageEditorElement, ImageEditorNodeConfig, DimensionPresetKey };
464
- export interface ImageEditorNodeInput extends Record<string, unknown> {
465
- type: 'image-composer';
466
- config: ImageEditorNodeConfig;
467
- imageUrls: Record<string, string>;
468
- textValues: Record<string, string>;
469
- }
470
- export interface ImageEditorNodeOutput extends Record<string, unknown>, NodeOutputValues {
471
- width?: number;
472
- height?: number;
473
- aspectRatio?: string;
474
- }
475
- export interface VideoEditorNodeInput extends Record<string, unknown> {
476
- type: 'video-composer';
477
- editor: VideoEditorNodeConfig;
478
- }
479
- export interface EditorConfig extends BaseEditorConfig {
480
- channels: Array<{
481
- id: string;
482
- segments: EditorSegment[];
483
- }>;
484
- }
485
- export interface EditorChannel {
486
- id: string;
487
- segments: EditorSegment[];
488
- }
489
- /**
490
- * Base properties for all segments
491
- */
492
- export interface BaseSegmentProps {
493
- /** Unique segment identifier */
494
- id: string;
495
- /** Public URL to media file */
496
- source: string;
497
- /** Sequence order within channel (0-based) */
498
- order: number;
499
- /** Time offset after previous segment starts */
500
- offset: TimeValue;
501
- /** Trim from start in milliseconds (default: 0) */
502
- startTrim?: number;
503
- /** Trim from end in milliseconds (default: 0) */
504
- endTrim?: number;
505
- /** Override segment duration (auto-calculated if omitted) */
506
- duration?: TimeValue;
507
- /**
508
- * Overlay support - if parentId is set, this segment's timing is relative to the parent.
509
- * The segment will appear on top of the parent segment during the specified time range.
510
- */
511
- /** ID of the parent segment this overlays (timing calculated relative to parent) */
512
- parentId?: string;
513
- /** Start time as fraction of parent duration (0-1, default: 0). Only used when parentId is set. */
514
- relativeStart?: number;
515
- /** End time as fraction of parent duration (0-1, default: 1). Only used when parentId is set. */
516
- relativeEnd?: number;
517
- /**
518
- * Fade-in effect - applies a black overlay that smoothly fades out over the specified duration.
519
- * The segment and all its overlays will appear to fade in from black.
520
- */
521
- /** Duration in milliseconds for the fade-in effect (0 or undefined = no fade) */
522
- fadeIn?: number;
523
- }
524
- /**
525
- * Border radius configuration for individual corners.
526
- * All values in pixels, default 0 (no rounding).
527
- */
528
- export interface BorderRadiusConfig {
529
- /** Top-left corner radius in pixels */
530
- topLeft?: number;
531
- /** Top-right corner radius in pixels */
532
- topRight?: number;
533
- /** Bottom-right corner radius in pixels */
534
- bottomRight?: number;
535
- /** Bottom-left corner radius in pixels */
536
- bottomLeft?: number;
537
- }
538
- /**
539
- * Vertical anchor for Y positioning (parent element)
540
- * Specifies which vertical edge of the reference element to anchor to
541
- */
542
- export type VerticalAnchor = 'top' | 'bottom';
543
- /**
544
- * Horizontal anchor for X positioning (parent element)
545
- * Specifies which horizontal edge of the reference element to anchor to
546
- */
547
- export type HorizontalAnchor = 'left' | 'right';
548
- /**
549
- * Self anchor for X positioning
550
- * Specifies which horizontal edge of THIS element to use for positioning
551
- */
552
- export type HorizontalSelfAnchor = 'left' | 'center' | 'right';
553
- /**
554
- * Self anchor for Y positioning
555
- * Specifies which vertical edge of THIS element to use for positioning
556
- */
557
- export type VerticalSelfAnchor = 'top' | 'middle' | 'bottom';
558
- /** @deprecated Use VerticalAnchor or HorizontalAnchor instead */
559
- export type PositionAnchor = 'top' | 'bottom' | 'left' | 'right';
560
- /**
561
- * Relative X position configuration
562
- * When set, the segment's X position is calculated relative to another segment
563
- */
564
- export interface RelativePositionConfigX {
565
- /** ID of the segment to position relative to */
566
- elementId: string;
567
- /** Which horizontal edge of the reference segment to anchor to */
568
- anchor: HorizontalAnchor;
569
- /** Which horizontal edge of THIS segment to use (default: opposite of anchor) */
570
- selfAnchor?: HorizontalSelfAnchor;
571
- /** Offset in pixels from the anchor point */
572
- offset: number;
573
- }
574
- /**
575
- * Relative Y position configuration
576
- * When set, the segment's Y position is calculated relative to another segment
577
- */
578
- export interface RelativePositionConfigY {
579
- /** ID of the segment to position relative to */
580
- elementId: string;
581
- /** Which vertical edge of the reference segment to anchor to */
582
- anchor: VerticalAnchor;
583
- /** Which vertical edge of THIS segment to use (default: opposite of anchor) */
584
- selfAnchor?: VerticalSelfAnchor;
585
- /** Offset in pixels from the anchor point */
586
- offset: number;
587
- }
588
- /** @deprecated Use RelativePositionConfigX and RelativePositionConfigY instead */
589
- export interface RelativePositionConfig {
590
- /** ID of the segment to position relative to */
591
- elementId: string;
592
- /** Which edge of the reference segment to anchor to */
593
- anchor: PositionAnchor;
594
- /** Offset in pixels from the anchor point (positive = away from reference) */
595
- offset: number;
596
- }
597
- /**
598
- * Visual segment properties (video, image, text, editor)
599
- */
600
- export interface VisualSegmentProps extends BaseSegmentProps {
601
- /** Horizontal position from left edge in pixels */
602
- xOffset: number;
603
- /** Vertical position from top edge in pixels */
604
- yOffset: number;
605
- /** Width in pixels */
606
- width: number;
607
- /** Height in pixels */
608
- height: number;
609
- /** Layer order - higher values appear on top (default: 0) */
610
- zIndex?: number;
611
- /** Scale multiplier (1.0 = 100%, 2.0 = 200%) (default: 1) */
612
- scale?: number;
613
- /** Rotation in degrees clockwise (default: 0) */
614
- rotation?: number;
615
- /** Opacity percentage 0-100 (default: 100) */
616
- opacity?: number;
617
- /**
618
- * Relative X positioning - when set, xOffset is calculated from the reference segment
619
- *
620
- * @example
621
- * // Position this segment to the right of another segment
622
- * relativePositionX: { elementId: 'message-1', anchor: 'right', offset: 10 }
623
- */
624
- relativePositionX?: RelativePositionConfigX;
625
- /**
626
- * Relative Y positioning - when set, yOffset is calculated from the reference segment
627
- * This is useful for stacking elements like text messages where the reference element's
628
- * height may vary based on text content.
629
- *
630
- * @example
631
- * // Position this segment below another segment with a 10px gap
632
- * relativePositionY: { elementId: 'message-1', anchor: 'bottom', offset: 10 }
633
- */
634
- relativePositionY?: RelativePositionConfigY;
635
- /** @deprecated Use relativePositionX and relativePositionY instead */
636
- relativePosition?: RelativePositionConfig;
637
- }
638
- /**
639
- * Video segment - displays video content with optional audio
640
- * Only available for video output type
641
- */
642
- export interface VideoSegment extends VisualSegmentProps {
643
- type: 'video';
644
- /** How video fits in bounds: cover (fill+crop), contain (fit+letterbox), fill (stretch) (default: 'cover') */
645
- fit?: 'cover' | 'contain' | 'fill';
646
- /** Playback speed multiplier (0.5 = half speed, 2.0 = double speed) (default: 1) */
647
- speed?: number;
648
- /** Audio volume percentage 0-100 (0 = muted, 100 = full) (default: 100) */
649
- volume?: number;
650
- /** Corner radius - single number for all corners, or object for individual corners (default: 0) */
651
- borderRadius?: number | BorderRadiusConfig;
652
- }
653
- /**
654
- * Audio segment - background audio or music
655
- * Only available for video output type
656
- */
657
- export interface AudioSegment extends BaseSegmentProps {
658
- type: 'audio';
659
- /** Audio volume percentage 0-100 (default: 100) */
660
- volume?: number;
661
- }
662
- /**
663
- * Image segment - static images or animated GIFs
664
- * Available for both video and image output types
665
- */
666
- export interface ImageSegment extends VisualSegmentProps {
667
- type: 'image';
668
- /** How image fits in bounds (default: 'contain') */
669
- fit?: 'cover' | 'contain' | 'fill';
670
- /** Loop animated GIFs (default: false) */
671
- loop?: boolean;
672
- /** Corner radius - single number for all corners, or object for individual corners (default: 0) */
673
- borderRadius?: number | BorderRadiusConfig;
674
- }
675
- /**
676
- * Text segment - rich text overlays with full typography control
677
- * Available for both video and image output types
678
- */
679
- export interface TextSegment extends VisualSegmentProps {
680
- type: 'text';
681
- source: '';
682
- /** The text content (supports emojis) */
683
- text: string;
684
- /** Horizontal alignment (default: 'left') */
685
- alignment?: 'left' | 'center' | 'right' | 'justify';
686
- /** Vertical alignment within bounds (default: 'top') */
687
- verticalAlign?: 'top' | 'middle' | 'bottom';
688
- /** Text direction (default: 'ltr') */
689
- direction?: 'ltr' | 'rtl';
690
- /** Inner padding in pixels - uniform for all sides (default: 0). Overridden by individual padding values if set. */
691
- padding?: number;
692
- /** Top padding in pixels (overrides uniform padding) */
693
- paddingTop?: number;
694
- /** Right padding in pixels (overrides uniform padding) */
695
- paddingRight?: number;
696
- /** Bottom padding in pixels (overrides uniform padding) */
697
- paddingBottom?: number;
698
- /** Left padding in pixels (overrides uniform padding) */
699
- paddingLeft?: number;
700
- /** Font family (default: 'tiktok') */
701
- fontType?: 'tiktok' | 'apple' | 'arial';
702
- /** Font size in pixels (default: 40) */
703
- fontSize?: number;
704
- /** Font weight (default: 'normal') */
705
- fontWeight?: 'normal' | 'bold';
706
- /** Line height multiplier (default: 1.2) */
707
- lineHeight?: number;
708
- /** Letter spacing in pixels (default: 0) */
709
- letterSpacing?: number;
710
- /** How text wraps to new lines (default: 'word') */
711
- textWrap?: 'word' | 'char' | 'none';
712
- /** How words break across lines (default: 'normal') */
713
- wordBreak?: 'normal' | 'break-all' | 'break-word';
714
- /** Automatic hyphenation (default: 'none') */
715
- hyphenation?: 'none' | 'auto';
716
- /** Maximum lines (0 = unlimited) (default: 0) */
717
- maxLines?: number;
718
- /** How overflow is handled (default: 'clip') */
719
- textOverflow?: 'clip' | 'ellipsis';
720
- /** Ellipsis string for overflow (default: '...') */
721
- ellipsis?: string;
722
- /** Text color (default: '#FFFFFF') */
723
- color?: string;
724
- /** Background color in hex format #RRGGBB (default: transparent) */
725
- backgroundColor?: string;
726
- /** Background opacity 0-100 (default: 100) */
727
- backgroundOpacity?: number;
728
- /** Border radius for background box - individual corners (default: 0) */
729
- backgroundBorderRadius?: BorderRadiusConfig;
730
- /** Text outline color (default: none) */
731
- strokeColor?: string;
732
- /** Outline width in pixels (default: 0) */
733
- strokeWidth?: number;
734
- /** When true, box shrinks to fit content (width becomes max width) */
735
- autoWidth?: boolean;
736
- /** Which side the box anchors to when autoWidth is true (default: 'left') */
737
- boxAlign?: 'left' | 'center' | 'right';
738
- }
739
- /**
740
- * Editor segment - nested composition (editor within editor)
741
- * Only available for video output type
742
- */
743
- export interface EditorSegment_Nested extends VisualSegmentProps {
744
- type: 'editor';
745
- /** Nested editor configuration */
746
- editor: EditorConfig;
747
- /** How rendered video fits in bounds (default: 'contain') */
748
- fit?: 'cover' | 'contain' | 'fill';
749
- /** Playback speed of nested composition (default: 1) */
750
- speed?: number;
751
- /** Audio volume of nested composition 0-100 (default: 100) */
752
- volume?: number;
753
- }
754
- export type EditorSegment = VideoSegment | AudioSegment | ImageSegment | TextSegment | EditorSegment_Nested;
755
- export type StaticSegment = ImageSegment | TextSegment;
756
- /**
757
- * Automation types
758
- */
759
- export type MediaType = 'video' | 'image' | 'audio' | 'text';
760
- /**
761
- * Base port type - all possible value types without array modifier
762
- */
763
- export type BasePortType = 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'object' | 'account' | 'date' | 'social_audio';
764
- /**
765
- * Structured port type descriptor
766
- * Replaces string-based types like 'image[]' with explicit { type, isArray }
767
- */
768
- export interface PortType {
769
- type: BasePortType;
770
- isArray: boolean;
771
- }
772
- /**
773
- * Helper to create a PortType descriptor
774
- */
775
- export declare function portType({ type, isArray }: {
776
- type: BasePortType;
777
- isArray: boolean;
778
- }): PortType;
779
- /**
780
- * Format a PortType for display (e.g., { type: 'image', isArray: true } -> 'image[]')
781
- */
782
- export declare function formatPortType(port: PortType): string;
783
- /**
784
- * @deprecated Legacy string-based port type. Use PortType interface instead.
785
- * Kept for backwards compatibility with existing saved automations.
786
- */
787
- export type LegacyPortType = 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'object' | 'account' | 'date' | 'social_audio' | 'image[]' | 'video[]' | 'audio[]' | 'text[]' | 'number[]' | 'boolean[]' | 'object[]' | 'account[]' | 'social_audio[]';
788
- /**
789
- * @deprecated Check if a value is a legacy string port type.
790
- * Use for runtime detection during migration.
791
- */
792
- export declare function isLegacyPortType(value: unknown): value is LegacyPortType;
793
- /**
794
- * @deprecated Convert legacy string port type to structured PortType.
795
- * Use for migrating old code and data.
796
- */
797
- export declare function fromLegacyPortType(legacy: LegacyPortType): PortType;
798
- /**
799
- * @deprecated Convert structured PortType to legacy string format.
800
- * Use only for backwards compatibility with systems expecting string types.
801
- */
802
- export declare function toLegacyPortType(port: PortType): LegacyPortType;
803
- /**
804
- * @deprecated Normalize port type - accepts either legacy string or structured format,
805
- * always returns structured PortType. Use at read boundaries during migration.
806
- */
807
- export declare function normalizePortType(value: LegacyPortType | PortType): PortType;
808
- /**
809
- * @deprecated Normalize an array of port types or a single port type.
810
- * Handles PortType | PortType[] | LegacyPortType | LegacyPortType[] formats.
811
- */
812
- export declare function normalizePortTypes(value: LegacyPortType | PortType | LegacyPortType[] | PortType[]): PortType | PortType[];
813
- /**
814
- * Selection order configuration for media nodes
815
- */
816
- export type SelectionMode = 'random' | 'sequential';
817
- export type ExhaustionBehavior = 'restart' | 'error';
818
- export interface SelectionConfig {
819
- mode?: SelectionMode;
820
- enforceUniqueness?: boolean;
821
- exhaustionBehavior?: ExhaustionBehavior;
822
- }
823
- export interface SelectionState {
824
- usedIndices: number[];
825
- currentIndex: number;
826
- }
827
- /**
828
- * Output mode for source nodes (image, video, audio, text)
829
- * - 'per-input': Generate a unique value for each consumer input (default)
830
- * - 'single': Use the same value for all consumer inputs
831
- */
832
- export type OutputMode = 'per-input' | 'single';
833
- /**
834
- * Standard node output format.
835
- * All nodes output their values in the _values array.
836
- * - For per-input mode: _values contains N values (one per consumer)
837
- * - For single mode: _values contains 1 value
838
- *
839
- * Downstream nodes always read from _values using resolveValueAtIteration().
840
- */
841
- export interface NodeOutputValues {
842
- _values: unknown[];
843
- _outputMode: OutputMode;
844
- }
845
- /**
846
- * Schema definition for a property within an array item
847
- */
848
- export interface PropertySchema {
849
- type: 'string' | 'number' | 'boolean' | 'object' | 'array';
850
- /** For arrays - the item type */
851
- items?: 'string' | 'number' | 'boolean' | 'object';
852
- /** For nested objects or array of objects */
853
- itemSchema?: Record<string, PropertySchema>;
854
- }
855
- export interface NodePort {
856
- id: string;
857
- type: PortType | PortType[];
858
- required: boolean;
859
- /** Schema of array items (when this port outputs an array) */
860
- itemSchema?: Record<string, PropertySchema>;
861
- }
862
- /**
863
- * Port definition for resolved/dynamic ports.
864
- * Stored in node config when the automation is saved.
865
- */
866
- export interface ResolvedPort {
867
- id: string;
868
- type: PortType | PortType[];
869
- required: boolean;
870
- /** Schema of array items (when this port outputs an array) */
871
- itemSchema?: Record<string, PropertySchema>;
872
- }
873
- /**
874
- * Resolved ports for nodes with dynamic inputs/outputs.
875
- * Stored in node config when the automation is saved, allowing validation
876
- * without needing to resolve ports at validation time.
877
- * Note: Uses simplified ResolvedPort type for database compatibility.
878
- */
879
- export interface ResolvedPorts {
880
- inputs: ResolvedPort[];
881
- outputs: ResolvedPort[];
882
- }
883
- /**
884
- * Functional category for automation nodes
885
- * - trigger: Nodes that start an automation (manual-trigger, recurrence)
886
- * - source: Nodes that provide input data (image, video, audio, social-audio, text, account)
887
- * - generator: Nodes that transform or generate content (image-composer, video-composer, generate-image, llm, compose-workflow)
888
- * - terminal: Nodes that end an automation (output, auto-post, save-to-media)
889
- */
890
- export type NodeCategory = 'trigger' | 'source' | 'generator' | 'terminal';
891
- export interface NodeControlConfig {
892
- type: string;
893
- label: string;
894
- description: string;
895
- /** UI display category for grouping in add node modal */
896
- category: string;
897
- /** Functional category for node behavior classification */
898
- nodeCategory: NodeCategory;
899
- inputs: NodePort[];
900
- outputs: NodePort[];
901
- /**
902
- * If true, this node supports generating multiple unique outputs per run
903
- * when outputMode is 'per-input'. Used for source nodes like image, audio, text.
904
- */
905
- supportsPerInputMode?: boolean;
906
- /**
907
- * @deprecated Use nodeCategory === 'trigger' instead
908
- * If true, this is an initializer node (starts an automation).
909
- * Only one initializer node is allowed per automation.
910
- * Manual Trigger and Recurrence nodes are initializers.
911
- */
912
- isInitializer?: boolean;
913
- }
914
- export type NodeTypeEnum = 'social-audio' | 'text' | 'media' | 'video-import' | 'image-composer' | 'video-composer' | 'generate-image' | 'generate-video' | 'custom-model' | 'llm' | 'output' | 'manual-trigger' | 'recurrence' | 'compose-workflow' | 'account' | 'auto-post' | 'save-to-media' | 'deduplicate' | 'for-each' | 'for-each-value' | 'random' | 'random-route' | 'branch' | 'if' | 'not' | 'transcript' | 'auto-caption' | 'screenshot-animation' | 'create-dm' | 'collect' | 'destructure';
915
- export interface OutputSchemaProperty {
916
- type: 'string' | 'number' | 'boolean' | 'array' | 'object';
917
- items?: 'string' | 'number' | 'boolean';
918
- properties?: Record<string, OutputSchemaProperty>;
919
- }
920
- /**
921
- * LLM output field definition for structured outputs
922
- */
923
- export interface LLMOutputField {
924
- /** Required - becomes the output port ID */
925
- name: string;
926
- /** Optional - guides LLM on expected content */
927
- description?: string;
928
- /** Output type (includes 'object' for top-level objects) */
929
- type: 'string' | 'number' | 'boolean' | 'array' | 'object';
930
- /** For array types - the item type (including 'object' for arrays of objects) */
931
- items?: 'string' | 'number' | 'boolean' | 'object';
932
- /** For array of objects or top-level objects - nested field definitions (max 3 levels of nesting) */
933
- objectSchema?: LLMOutputField[];
934
- /** Exact array length constraint */
935
- length?: number;
936
- /** Minimum array length constraint */
937
- minLength?: number;
938
- /** Maximum array length constraint */
939
- maxLength?: number;
940
- /** Whether this output is optional (can be omitted by the LLM) */
941
- optional?: boolean;
942
- }
943
- /**
944
- * API Keys configuration for LLM providers (user can bring their own)
945
- */
946
- export interface LLMApiKeys {
947
- openai?: string;
948
- claude?: string;
949
- gemini?: string;
950
- groq?: string;
951
- }
952
- /**
953
- * LLM Node Configuration
954
- */
955
- export interface LLMNodeConfig {
956
- provider: 'groq' | 'openai' | 'claude' | 'gemini';
957
- model: string;
958
- temperature?: number;
959
- maxTokens?: number;
960
- systemPrompt: string;
961
- outputFields: LLMOutputField[];
962
- useStructuredOutput?: boolean;
963
- imageInputRefs?: string[];
964
- videoInputRefs?: string[];
965
- apiKeys?: LLMApiKeys;
966
- }
967
- /**
968
- * Image Generation Model IDs
969
- * Text-only models take just a prompt, edit models require an image input
970
- */
971
- export type ImageGenerationTextModel = 'fal-ai/gemini-3-pro-image-preview' | 'fal-ai/nano-banana-pro' | 'fal-ai/nano-banana' | 'fal-ai/gpt-image-1/text-to-image';
972
- export type ImageGenerationEditModel = 'fal-ai/gemini-3-pro-image-preview/edit' | 'fal-ai/nano-banana-pro/edit' | 'fal-ai/nano-banana/edit' | 'fal-ai/gpt-image-1/edit-image';
973
- export type ImageGenerationModel = ImageGenerationTextModel | ImageGenerationEditModel;
974
- /**
975
- * Type guard to check if model is an edit/inpaint model
976
- */
977
- export declare function isEditModel(model: ImageGenerationModel): model is ImageGenerationEditModel;
978
- /**
979
- * Image Generation Node Configuration
980
- */
981
- export interface ImageGenerationNodeConfig {
982
- /** Selected model ID */
983
- model: ImageGenerationModel;
984
- /** Custom fal.ai API key (optional - uses platform key if not provided) */
985
- apiKey?: string;
986
- /** Image aspect ratio (e.g., "1:1", "16:9", "9:16") */
987
- aspectRatio?: string;
988
- /** Number of images to generate (default: 1) */
989
- numImages?: number;
990
- }
991
- export interface WorkflowNodeDefinition {
992
- id: string;
993
- type: NodeTypeEnum;
994
- name?: string;
995
- x?: number;
996
- y?: number;
997
- inputs: Record<string, {
998
- sourceNodeId: string;
999
- sourceOutputId: string;
1000
- }>;
1001
- config?: {
1002
- urls?: string[];
1003
- selectionConfig?: SelectionConfig;
1004
- selectionState?: SelectionState;
1005
- outputMode?: OutputMode;
1006
- textOptions?: string[];
1007
- videoEditor?: VideoEditorNodeConfig;
1008
- imageEditor?: ImageEditorNodeConfig;
1009
- imageGeneration?: ImageGenerationNodeConfig;
1010
- llm?: LLMNodeConfig;
1011
- outputSchema?: Record<string, OutputSchemaProperty>;
1012
- provider?: 'groq' | 'openai' | 'claude' | 'gemini';
1013
- model?: string;
1014
- temperature?: number;
1015
- maxTokens?: number;
1016
- useWebSearch?: boolean;
1017
- useStructuredOutput?: boolean;
1018
- manualTriggerConfig?: ManualTriggerNodeConfig;
1019
- recurrenceConfig?: RecurrenceNodeConfig;
1020
- workflowTemplateId?: string;
1021
- workflowVariableNameToIdMap?: Record<string, string>;
1022
- workflowPassThrough?: Record<string, boolean>;
1023
- /** Resolved ports from the sub-workflow template (for validation) */
1024
- resolvedPorts?: ResolvedPorts;
1025
- outputConfig?: OutputNodeConfig;
1026
- accountConfig?: AccountNodeConfig;
1027
- mediaConfig?: MediaNodeConfig;
1028
- autoPostConfig?: AutoPostNodeConfig;
1029
- saveToMediaConfig?: SaveToMediaNodeConfig;
1030
- deduplicateConfig?: DeduplicateNodeConfig;
1031
- videoImportConfig?: VideoImportNodeConfig;
1032
- videoGeneration?: VideoGenerationNodeConfig;
1033
- customModelConfig?: CustomModelNodeConfig;
1034
- forEachConfig?: ForEachNodeConfig;
1035
- randomConfig?: RandomNodeConfig;
1036
- ifConfig?: IfNodeConfig;
1037
- randomRouteConfig?: RandomRouteNodeConfig;
1038
- branchConfig?: BranchNodeConfig;
1039
- autoCaptionConfig?: AutoCaptionNodeConfig;
1040
- screenshotAnimationConfig?: ScreenshotAnimationNodeConfig;
1041
- createDmConfig?: CreateDmNodeConfig;
1042
- collectConfig?: CollectNodeConfig;
1043
- destructureConfig?: DestructureNodeConfig;
1044
- };
1045
- }
1046
- export interface OutputInput {
1047
- id: string;
1048
- title?: string;
1049
- type: 'image' | 'video' | 'audio' | 'text' | 'social_audio' | 'account' | 'boolean' | 'object';
1050
- /** Individual tag for this input (overrides global tag) */
1051
- tag?: string;
1052
- /** Whether this input accepts an array */
1053
- isArray?: boolean;
1054
- /** Schema of array items (when isArray is true) */
1055
- itemSchema?: Record<string, PropertySchema>;
1056
- }
1057
- export interface OutputNodeConfig {
1058
- inputs: OutputInput[];
1059
- /** Which input is the main visual preview for the workflow */
1060
- mainPreviewInputId?: string;
1061
- saveToMedia?: boolean;
1062
- globalTag?: string;
1063
- makeUnique?: boolean;
1064
- createPost?: boolean;
1065
- requireReview?: boolean;
1066
- }
1067
- /**
1068
- * Level 3 (deepest) object schema field - primitives only, no further nesting
1069
- */
1070
- export interface ObjectSchemaFieldLevel3 {
1071
- name: string;
1072
- type: 'string' | 'number' | 'boolean';
1073
- }
1074
- /**
1075
- * Level 2 object schema field - can contain primitives, arrays of primitives, or Level 3 nested objects
1076
- */
1077
- export interface ObjectSchemaFieldLevel2 {
1078
- name: string;
1079
- type: 'string' | 'number' | 'boolean' | 'object' | 'array';
1080
- /** For arrays - the item type (primitives only at this level) */
1081
- items?: 'string' | 'number' | 'boolean';
1082
- /** For nested objects at level 2 - can only contain primitive fields */
1083
- objectSchema?: ObjectSchemaFieldLevel3[];
1084
- }
1085
- /**
1086
- * Level 1 (top-level) object schema field - can contain primitives, arrays (including of objects), or Level 2 nested objects
1087
- */
1088
- export interface ObjectSchemaField {
1089
- name: string;
1090
- type: 'string' | 'number' | 'boolean' | 'object' | 'array';
1091
- /** For arrays - the item type */
1092
- items?: 'string' | 'number' | 'boolean' | 'object';
1093
- /** For nested objects or array of objects at level 1 - can contain up to one more level of nesting */
1094
- objectSchema?: ObjectSchemaFieldLevel2[];
1095
- }
1096
- /**
1097
- * Manual Trigger node output definition
1098
- */
1099
- export interface ManualTriggerOutput {
1100
- id: string;
1101
- type: 'image' | 'video' | 'audio' | 'text' | 'social_audio' | 'account' | 'boolean' | 'object';
1102
- isArray?: boolean;
1103
- /** Schema for object types - describes the structure of the object */
1104
- objectSchema?: ObjectSchemaField[];
1105
- }
1106
- /**
1107
- * Iteration mode for trigger nodes with account iteration
1108
- * - 'fan-out': Spawn all runs simultaneously (one per account)
1109
- * - 'sequential': One account per trigger fire, cycling through the collection
1110
- */
1111
- export type TriggerIterationMode = 'fan-out' | 'sequential';
1112
- /**
1113
- * Behavior when sequential iteration exhausts all accounts
1114
- * - 'repeat': Start from the beginning of the collection
1115
- * - 'stop': Stop the automation (disable schedule for recurrence)
1116
- */
1117
- export type IterationExhaustionBehavior = 'repeat' | 'stop';
1118
- /**
1119
- * Selection mode for collection inputs
1120
- * - 'specific': Use hardcoded IDs configured at design time
1121
- * - 'by-tag': Query items by tag at runtime (allows dynamic collections)
1122
- */
1123
- export type CollectionSelectionMode = 'specific' | 'by-tag';
1124
- /**
1125
- * Account iteration configuration for trigger nodes
1126
- * When enabled, the trigger iterates over a collection of accounts
1127
- */
1128
- export interface TriggerCollectionConfig {
1129
- /** Whether account iteration is enabled */
1130
- enabled: boolean;
1131
- /** Selection mode: 'specific' uses accountIds, 'by-tag' queries at runtime */
1132
- selectionMode?: CollectionSelectionMode;
1133
- /** Account IDs to iterate over (used when selectionMode is 'specific' or undefined) */
1134
- accountIds?: string[];
1135
- /** Tag to query accounts by at runtime (used when selectionMode is 'by-tag') */
1136
- accountTag?: string;
1137
- }
1138
- /**
1139
- * Manual Trigger node configuration - defines outputs that users provide when running
1140
- */
1141
- export interface ManualTriggerNodeConfig {
1142
- outputs: ManualTriggerOutput[];
1143
- }
1144
- /**
1145
- * Days of the week for recurrence scheduling
1146
- */
1147
- export type DayOfWeek = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
1148
- /**
1149
- * Recurrence media output port definition
1150
- * Each output is a named port with a specific media type and its own selection config
1151
- */
1152
- export interface RecurrenceMediaOutput {
1153
- /** Unique ID for this output port (e.g., "background-image", "overlay") */
1154
- id: string;
1155
- /** Media type for this port */
1156
- type: 'image' | 'video' | 'audio' | 'text' | 'social_audio';
1157
- /** Selection mode for this output's media source */
1158
- selectionMode: 'specific' | 'by-tag';
1159
- /** Media IDs for this output (used when selectionMode is 'specific') */
1160
- selectedMediaIds?: string[];
1161
- /** Tag to query media by at runtime (used when selectionMode is 'by-tag') */
1162
- mediaTag?: string;
1163
- }
1164
- /**
1165
- * Media input configuration for recurrence nodes
1166
- * Each output has its own selection configuration
1167
- */
1168
- export interface RecurrenceMediaConfig {
1169
- /** Whether media input is enabled */
1170
- enabled: boolean;
1171
- /** Named output ports - each has its own selection config */
1172
- outputs: RecurrenceMediaOutput[];
1173
- }
1174
- /**
1175
- * Recurrence node configuration - defines when the automation runs on a schedule
1176
- */
1177
- export interface RecurrenceNodeConfig {
1178
- frequencyType: 'per-day' | 'periodic';
1179
- runsPerDay: number;
1180
- periodDays: number;
1181
- daysOfWeek: DayOfWeek[];
1182
- timingType: 'specific' | 'random-window';
1183
- specificTimes: string[];
1184
- randomWindowStart: string;
1185
- randomWindowEnd: string;
1186
- timezone: string;
1187
- /** Optional collection input for iterating over multiple accounts */
1188
- collectionInput?: TriggerCollectionConfig;
1189
- /** Optional media input for providing media to downstream nodes */
1190
- mediaInput?: RecurrenceMediaConfig;
1191
- }
1192
- /**
1193
- * Account node configuration - source node for selecting accounts to post from
1194
- */
1195
- export interface AccountNodeConfig {
1196
- /** List of account IDs to choose from */
1197
- accountIds: string[];
1198
- /** Selection mode */
1199
- selectionConfig?: {
1200
- mode?: 'random' | 'sequential';
1201
- };
1202
- }
1203
- /**
1204
- * Media node enabled type (image, video, or audio)
1205
- * Note: text is NOT supported in the regular media node
1206
- */
1207
- export type MediaNodeEnabledType = 'image' | 'video' | 'audio';
1208
- /**
1209
- * Recurrence media enabled type
1210
- * Includes all media types that can be output from recurrence nodes
1211
- */
1212
- export type RecurrenceMediaEnabledType = 'image' | 'video' | 'audio' | 'text' | 'social_audio';
1213
- /**
1214
- * Media node output definition
1215
- * Each output is a named port with a specific media type
1216
- */
1217
- export interface MediaNodeOutput {
1218
- /** Unique ID for this output port (e.g., "image-1", "background-video") */
1219
- id: string;
1220
- /** Base media type for this port */
1221
- type: MediaNodeEnabledType;
1222
- /** If true, output is an array of URLs; if false, single URL */
1223
- isArray: boolean;
1224
- /** Selected media IDs for this output */
1225
- selectedMediaIds: string[];
1226
- /** Selection configuration for this output (only used when isArray is false) */
1227
- selectionConfig?: SelectionConfig;
1228
- }
1229
- /**
1230
- * Media node configuration - consolidated source node for image, video, and audio
1231
- */
1232
- export interface MediaNodeConfig {
1233
- /** Output ports for this media node */
1234
- outputs: MediaNodeOutput[];
1235
- }
1236
- /**
1237
- * Scheduling mode for post nodes
1238
- * - 'scheduled': Post immediately when automation runs
1239
- * - 'queue': Automatically schedule based on queue constraints
1240
- */
1241
- export type PostSchedulingMode = 'scheduled' | 'queue';
1242
- /**
1243
- * Post scheduling configuration for post nodes
1244
- */
1245
- export interface PostSchedulingConfig {
1246
- /** Main scheduling mode ('scheduled' = post now, 'queue' = auto-schedule) */
1247
- mode: PostSchedulingMode;
1248
- /** Minimum hours between posts for this account (min 1) */
1249
- minDistanceHours?: number;
1250
- /** Maximum posts per day for this account (min 1) */
1251
- maxPostsPerDay?: number;
1252
- /** Minimum time of day for posting (HH:mm format, e.g., '09:00') */
1253
- randomWindowStart?: string;
1254
- /** Maximum time of day for posting (HH:mm format, e.g., '21:00') */
1255
- randomWindowEnd?: string;
1256
- /** Timezone for time window (IANA timezone, e.g., 'America/New_York') */
1257
- timezone?: string;
1258
- /** If true, post will be created with 'require-approval' status instead of being posted */
1259
- requireApproval?: boolean;
1260
- }
1261
- /**
1262
- * Auto Post mode - video or slideshow
1263
- */
1264
- export type AutoPostMode = 'video' | 'slideshow';
1265
- /**
1266
- * Auto Post input type for slideshow mode
1267
- * - 'static': Individual image input ports (image1, image2, etc.)
1268
- * - 'variable': Single 'images' port accepting an array
1269
- */
1270
- export type AutoPostInputType = 'static' | 'variable';
1271
- /**
1272
- * Auto Post input definition (for slideshow static mode)
1273
- */
1274
- export interface AutoPostInput {
1275
- id: string;
1276
- }
1277
- /**
1278
- * Auto Post node configuration - posts a video or slideshow to social media
1279
- */
1280
- export interface AutoPostNodeConfig {
1281
- /** Post mode - video or slideshow */
1282
- mode: AutoPostMode;
1283
- /** Input type for slideshow mode (defaults to 'static') */
1284
- inputType?: AutoPostInputType;
1285
- /** Dynamic image inputs (only used in slideshow mode with inputType='static') */
1286
- inputs?: AutoPostInput[];
1287
- /** Scheduling configuration */
1288
- scheduling?: PostSchedulingConfig;
1289
- /** Social audio configuration */
1290
- socialAudio?: {
1291
- /** If true, read from input port; if false, use selectedIds */
1292
- isVariable: boolean;
1293
- /** Selected social audio IDs (when isVariable is false) - one is randomly chosen when posting */
1294
- selectedIds?: string[];
1295
- };
1296
- }
1297
- /**
1298
- * Save To Media node input definition
1299
- */
1300
- export interface SaveToMediaInput {
1301
- id: string;
1302
- title?: string;
1303
- type: 'image' | 'video' | 'audio' | 'text';
1304
- /** Optional individual tag for this input (overrides global tag) */
1305
- tag?: string;
1306
- }
1307
- /**
1308
- * Save To Media node configuration - saves outputs to media library
1309
- */
1310
- export interface SaveToMediaNodeConfig {
1311
- /** Dynamic inputs to save */
1312
- inputs: SaveToMediaInput[];
1313
- /** Global tag applied to all saved items */
1314
- globalTag?: string;
1315
- /** If true, append date in mm-dd-yy format to tag */
1316
- includeDateTag?: boolean;
1317
- /** If true, append run ID to make tags unique */
1318
- makeUnique?: boolean;
1319
- }
1320
- /**
1321
- * Deduplicate node configuration - makes videos unique for social platforms
1322
- */
1323
- export interface DeduplicateNodeConfig {
1324
- /** Deduplication settings - preset level or custom config */
1325
- deduplication: DeduplicationInput;
1326
- }
1327
- /**
1328
- * For-each output property configuration
1329
- * Maps a property path from the item object to an output port.
1330
- * For media array elements (image[], video[], audio[]), use empty propertyPath
1331
- * with the corresponding media type.
1332
- */
1333
- export interface ForEachOutputProperty {
1334
- /** The output port ID (lowercase, hyphens/underscores only) */
1335
- portId: string;
1336
- /** The property path to extract from each item (e.g., "startMs", "data.value"). Empty string means the whole element. */
1337
- propertyPath: string;
1338
- /** The output type for the port */
1339
- type: 'text' | 'object' | 'object[]' | 'image' | 'video' | 'audio' | 'account' | 'social_audio' | 'boolean';
1340
- }
1341
- /**
1342
- * For-each input port configuration
1343
- * Defines passthrough inputs that capture single values before expansion
1344
- * and pass them unchanged to all iterations (Mode 2: Single-Value Passthrough)
1345
- */
1346
- export interface ForEachInputPort {
1347
- /** The port ID (lowercase, hyphens/underscores only) */
1348
- id: string;
1349
- /** Display title for the port */
1350
- title: string;
1351
- /** The port type */
1352
- type: 'image' | 'video' | 'audio' | 'text' | 'object' | 'account' | 'social_audio' | 'boolean';
1353
- }
1354
- /**
1355
- * For-each node configuration
1356
- */
1357
- export interface ForEachNodeConfig {
1358
- /** Properties to extract from each item and expose as separate outputs */
1359
- outputProperties?: ForEachOutputProperty[];
1360
- /** Input ports for single-value passthrough (Mode 2) */
1361
- inputPorts?: ForEachInputPort[];
1362
- /** Whether to expose the full item object as an output (default: false) */
1363
- exposeItem?: boolean;
1364
- /** Whether to expose the iteration index as an output (default: false) */
1365
- exposeIndex?: boolean;
1366
- }
1367
- /**
1368
- * Random node value type - determines the type for all inputs and outputs
1369
- */
1370
- export type RandomValueType = 'image' | 'video' | 'audio' | 'text' | 'object' | 'account' | 'boolean';
1371
- /**
1372
- * Random node input port configuration (for multi-input mode)
1373
- * Each input has an associated probability weight
1374
- */
1375
- export interface RandomInputPort {
1376
- /** The port ID (lowercase, hyphens/underscores only) */
1377
- id: string;
1378
- /** Probability weight as integer (0-100, all must sum to 100) */
1379
- probability: number;
1380
- /** Whether this input comes from a variable (input port) vs static default value. Defaults to false. */
1381
- isVariable?: boolean;
1382
- /** Default value when isVariable is false (type depends on valueType) */
1383
- defaultValue?: unknown;
1384
- }
1385
- /**
1386
- * Random node mode
1387
- * - 'array': Select a random element from an array input
1388
- * - 'multi-input': Select from multiple individual inputs with weighted probabilities
1389
- */
1390
- export type RandomNodeMode = 'array' | 'multi-input';
1391
- /**
1392
- * Random node configuration - randomly selects from array or weighted inputs
1393
- */
1394
- export interface RandomNodeConfig {
1395
- /** Selection mode */
1396
- mode: RandomNodeMode;
1397
- /** Type for all inputs/outputs (enforced to be uniform) */
1398
- valueType: RandomValueType;
1399
- /** Whether to expose the selected index as an output (array mode only, default: false) */
1400
- exposeIndex?: boolean;
1401
- /** Input ports with probability weights (multi-input mode only) */
1402
- inputPorts?: RandomInputPort[];
1403
- }
1404
- /**
1405
- * If node logic operators
1406
- */
1407
- export type IfLogicOperator = 'and' | 'or' | 'xor' | 'nor';
1408
- /**
1409
- * If node boolean input - receives boolean values for logic evaluation
1410
- */
1411
- export interface IfBooleanInput {
1412
- /** The input port ID (lowercase, hyphens/underscores only) */
1413
- id: string;
1414
- }
1415
- /**
1416
- * If node passthrough input - values that get routed to true/false outputs
1417
- */
1418
- export interface IfPassthroughInput {
1419
- /** The input port ID (lowercase, hyphens/underscores only) */
1420
- id: string;
1421
- /** The value type */
1422
- type: 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'account' | 'object';
1423
- /** Whether this is an array type */
1424
- isArray?: boolean;
1425
- }
1426
- /**
1427
- * If node configuration - conditional branching based on boolean logic
1428
- */
1429
- export interface IfNodeConfig {
1430
- /** Logic operator to combine boolean inputs */
1431
- logicOperator: IfLogicOperator;
1432
- /** Boolean inputs for logic evaluation (at least one required) */
1433
- booleanInputs: IfBooleanInput[];
1434
- /** Passthrough inputs that get routed to true/false outputs (at least one required) */
1435
- passthroughInputs: IfPassthroughInput[];
1436
- }
1437
- /**
1438
- * Random Branch branch definition
1439
- */
1440
- export interface RandomRouteBranch {
1441
- /** Unique ID for this branch (e.g., "branch-1") */
1442
- id: string;
1443
- /** Probability weight (0-100, all branches must sum to 100) */
1444
- probability: number;
1445
- }
1446
- /**
1447
- * Object field definition for Random Branch passthrough input default values
1448
- */
1449
- export interface RandomRouteObjectField {
1450
- /** Field name */
1451
- name: string;
1452
- /** Field type */
1453
- type: 'string' | 'number' | 'boolean';
1454
- }
1455
- /**
1456
- * Random Branch passthrough input definition
1457
- */
1458
- export interface RandomRoutePassthroughInput {
1459
- /** The input port ID (lowercase, hyphens/underscores only) */
1460
- id: string;
1461
- /** The value type */
1462
- type: 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'account' | 'object';
1463
- /** Whether this is an array type */
1464
- isArray?: boolean;
1465
- /** Whether this input comes from a variable (input port) vs static default value. Defaults to false. */
1466
- isVariable?: boolean;
1467
- /** Default value when isVariable is false (type depends on type field) */
1468
- defaultValue?: unknown;
1469
- /** Object schema for object type (when type is 'object') */
1470
- objectSchema?: RandomRouteObjectField[];
1471
- }
1472
- /**
1473
- * Random Branch node configuration - routes inputs to a randomly selected branch based on probability
1474
- */
1475
- export interface RandomRouteNodeConfig {
1476
- /** Output branches with probability weights (must sum to 100) */
1477
- branches: RandomRouteBranch[];
1478
- /** Passthrough inputs that get routed to one branch's outputs */
1479
- passthroughInputs: RandomRoutePassthroughInput[];
1480
- }
1481
- /**
1482
- * Branch node branch definition
1483
- */
1484
- export interface BranchDefinition {
1485
- /** The key to match against (e.g., "happy", "sad", "neutral") */
1486
- key: string;
1487
- }
1488
- /**
1489
- * Per-branch value configuration - each branch can independently be variable or static
1490
- */
1491
- export type BranchValueConfig = {
1492
- isVariable: true;
1493
- } | {
1494
- isVariable: false;
1495
- value: unknown;
1496
- };
1497
- /**
1498
- * Branch node passthrough input definition
1499
- */
1500
- export interface BranchPassthroughInput {
1501
- /** The input port ID (lowercase, hyphens/underscores only) */
1502
- id: string;
1503
- /** The value type */
1504
- type: 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'account' | 'object';
1505
- /** Whether this is an array type */
1506
- isArray?: boolean;
1507
- /** Per-branch value configuration. Key is branch key. Each branch can be variable (input port) or static (value). */
1508
- branchValues?: Record<string, BranchValueConfig>;
1509
- /** Object schema for object type (when type is 'object') */
1510
- objectSchema?: RandomRouteObjectField[];
1511
- }
1512
- /**
1513
- * Branch node configuration - routes inputs to a branch based on key match
1514
- */
1515
- export interface BranchNodeConfig {
1516
- /** Output branches with keys to match against */
1517
- branches: BranchDefinition[];
1518
- /** Passthrough inputs that get routed to the matched branch's outputs */
1519
- passthroughInputs: BranchPassthroughInput[];
1520
- /** Optional default branch key if no match is found */
1521
- defaultBranchKey?: string;
1522
- /** Output mode - 'single' broadcasts one output to all consumers, 'per-input' creates one per consumer */
1523
- outputMode?: OutputMode;
1524
- }
1525
- /**
1526
- * Supported platforms for video import
1527
- * Note: YouTube is not yet implemented
1528
- */
1529
- export type VideoImportPlatform = 'youtube' | 'tiktok' | 'instagram';
1530
- /**
1531
- * Video quality options for video import
1532
- */
1533
- export type VideoImportQuality = '360' | '480' | '720' | '1080' | '1440' | '2160';
1534
- /**
1535
- * Video Import node configuration - imports videos from social media platforms
1536
- * Note: URL is received via input port, not stored in config
1537
- */
1538
- export interface VideoImportNodeConfig {
1539
- /** Platform to import from */
1540
- platform: VideoImportPlatform;
1541
- /** Video quality preference */
1542
- videoQuality?: VideoImportQuality;
1543
- }
1544
- /**
1545
- * Auto Caption preset styles
1546
- */
1547
- export type AutoCaptionPreset = 'hormozi' | 'minimal' | 'bold-pop' | 'clean' | 'neon';
1548
- /**
1549
- * Auto Caption font weight options
1550
- */
1551
- export type AutoCaptionFontWeight = 'normal' | 'bold' | 'black';
1552
- /**
1553
- * Auto Caption position options
1554
- */
1555
- export type AutoCaptionPosition = 'top' | 'center' | 'bottom';
1556
- /**
1557
- * Auto Caption node configuration - adds TikTok-style captions to videos
1558
- */
1559
- export interface AutoCaptionNodeConfig {
1560
- /** Preset style (if set, other values are derived from preset) */
1561
- preset?: AutoCaptionPreset;
1562
- /** Google Font name */
1563
- fontName?: string;
1564
- /** Font size in pixels (20-150) */
1565
- fontSize?: number;
1566
- /** Font weight */
1567
- fontWeight?: AutoCaptionFontWeight;
1568
- /** Main text color */
1569
- fontColor?: string;
1570
- /** Highlighted/active word color */
1571
- highlightColor?: string;
1572
- /** Text stroke/outline color */
1573
- strokeColor?: string;
1574
- /** Stroke width in pixels (0-10) */
1575
- strokeWidth?: number;
1576
- /** Background color behind text */
1577
- backgroundColor?: string;
1578
- /** Vertical position */
1579
- position?: AutoCaptionPosition;
1580
- /** Vertical offset in pixels from position anchor */
1581
- yOffset?: number;
1582
- /** Maximum width as percentage of video width (0-100) */
1583
- maxWidth?: number;
1584
- /** Words per subtitle segment (1-12) */
1585
- wordsPerSubtitle?: number;
1586
- /** Enable bounce animation effect */
1587
- enableAnimation?: boolean;
1588
- /** Language code for transcription */
1589
- language?: string;
1590
- }
1591
- /**
1592
- * Screenshot Animation node configuration - creates an iPhone screenshot animation video
1593
- */
1594
- export interface ScreenshotAnimationNodeConfig {
1595
- /** Duration to hold at end after animation completes (ms) - default 500 */
1596
- holdDurationMs?: number;
1597
- }
1598
- /**
1599
- * Message in a Create DM conversation
1600
- */
1601
- export interface CreateDmMessage {
1602
- /** Who sent this message */
1603
- sender: 'user' | 'recipient';
1604
- /** Message text content */
1605
- text: string;
1606
- /** Whether this message has an associated image (story reply for IG, sender image for iMessage) */
1607
- hasImage?: boolean;
1608
- }
1609
- /**
1610
- * Create DM node configuration - renders fake DM conversations for iMessage or Instagram
1611
- */
1612
- export interface CreateDmNodeConfig {
1613
- /** Platform to render */
1614
- platform: 'imessage' | 'instagram';
1615
- /** Whether platform comes from input port */
1616
- platformIsVariable?: boolean;
1617
- /** Light or dark mode */
1618
- lightMode: boolean;
1619
- /** Whether light mode comes from input port */
1620
- lightModeIsVariable?: boolean;
1621
- /** Username displayed in header */
1622
- username: string;
1623
- /** Whether username comes from input port */
1624
- usernameIsVariable?: boolean;
1625
- /** Status bar time */
1626
- time: string;
1627
- /** Whether status bar time comes from input port */
1628
- timeIsVariable?: boolean;
1629
- /** Profile picture URL (fallback if profilePic input not connected) */
1630
- profilePicUrl?: string;
1631
- /** Whether profile pic comes from input port */
1632
- profilePicIsVariable?: boolean;
1633
- /** Source of messages: 'config' uses static messages, 'input' uses messages from input port */
1634
- messagesSource: 'config' | 'input';
1635
- /** Static messages (used when messagesSource === 'config') */
1636
- messages?: CreateDmMessage[];
1637
- /** Image attachment URL (story reply for IG, sender image for iMessage) */
1638
- imageAttachmentUrl?: string;
1639
- /** Whether image attachment comes from input port */
1640
- imageAttachmentIsVariable?: boolean;
1641
- /** iMessage-specific settings */
1642
- imessage?: {
1643
- senderBubbleColor?: string;
1644
- showReadReceipt: boolean;
1645
- readReceiptText: string;
1646
- /** Whether read receipt time comes from input port */
1647
- readReceiptTimeIsVariable?: boolean;
1648
- unreadBadgeText: string;
1649
- /** Whether unread badge comes from input port */
1650
- unreadBadgeIsVariable?: boolean;
1651
- messageHeaderTimestampText: string;
1652
- /** Whether message header time comes from input port */
1653
- messageHeaderTimeIsVariable?: boolean;
1654
- };
1655
- /** Instagram-specific settings */
1656
- instagram?: {
1657
- userHasStory: boolean;
1658
- };
1659
- }
1660
- /**
1661
- * Collect node configuration - collects outputs from for-each loop into an array
1662
- * Note: Most config is set during expansion, not by user
1663
- */
1664
- export interface CollectNodeConfig {
1665
- /** Expected number of items to collect (set during for-each expansion) */
1666
- expectedCount?: number;
1667
- /** Template ID of the for-each loop this collects from (for validation) */
1668
- forEachTemplateId?: string;
1669
- }
1670
- /**
1671
- * Destructure node selection - defines which indexes to extract from an array
1672
- */
1673
- export interface DestructureSelection {
1674
- /** Port ID for this selection output (lowercase, hyphens/underscores only) */
1675
- portId: string;
1676
- /** Index expression: single index "0", comma-separated "0, 2, 4", ranges "0-3", or mixed "0, 2-4, 7" */
1677
- indexExpr: string;
1678
- /** Optional property path to extract from selected items (e.g., "messages", "data.items") */
1679
- propertyPath?: string;
1680
- /** If true, read indexExpr from input port (idx-{portId}) instead of using static value */
1681
- isVariable?: boolean;
1682
- }
1683
- /**
1684
- * Destructure node configuration - extracts specific elements from an array
1685
- */
1686
- export interface DestructureNodeConfig {
1687
- /** List of selections - each becomes an output port */
1688
- selections: DestructureSelection[];
1689
- }
1690
- /**
1691
- * Video Generation Model IDs
1692
- * Text-to-video models take just a prompt, image-to-video models require an image input
1693
- */
1694
- export type VideoGenerationTextToVideoModel = 'fal-ai/veo3.1' | 'fal-ai/veo3' | 'fal-ai/veo3/fast' | 'fal-ai/kling-video/v2.6/pro/text-to-video' | 'fal-ai/kling-video/v2.5/pro/text-to-video' | 'fal-ai/luma-dream-machine/ray-2' | 'fal-ai/luma-dream-machine/ray-2-flash' | 'fal-ai/minimax/hailuo-2.3/pro/text-to-video' | 'wan/v2.6/text-to-video' | 'fal-ai/sora-2/text-to-video';
1695
- export type VideoGenerationImageToVideoModel = 'fal-ai/veo3.1/image-to-video' | 'fal-ai/veo3/image-to-video' | 'fal-ai/kling-video/v2.6/pro/image-to-video' | 'fal-ai/kling-video/v2.5/pro/image-to-video' | 'fal-ai/luma-dream-machine/ray-2/image-to-video' | 'fal-ai/luma-dream-machine/ray-2-flash/image-to-video' | 'fal-ai/minimax/hailuo-2.3/pro/image-to-video' | 'wan/v2.6/image-to-video' | 'fal-ai/sora-2/image-to-video/pro';
1696
- export type VideoGenerationModel = VideoGenerationTextToVideoModel | VideoGenerationImageToVideoModel;
1697
- /**
1698
- * Type guard to check if model is an image-to-video model
1699
- */
1700
- export declare function isImageToVideoModel(model: VideoGenerationModel): model is VideoGenerationImageToVideoModel;
1701
- /**
1702
- * Video Generation node configuration - AI video generation
1703
- */
1704
- export interface VideoGenerationNodeConfig {
1705
- /** Selected model ID */
1706
- model: VideoGenerationModel;
1707
- /** Custom fal.ai API key (optional - uses platform key if not provided) */
1708
- apiKey?: string;
1709
- /** Video aspect ratio (e.g., "16:9", "9:16", "1:1") */
1710
- aspectRatio?: string;
1711
- /** Video duration in seconds (model-dependent) */
1712
- duration?: number;
1713
- }
1714
- /**
1715
- * Custom Model input parameter type
1716
- */
1717
- export type CustomModelParamType = 'string' | 'number' | 'boolean' | 'image' | 'video' | 'audio';
1718
- /**
1719
- * Custom Model input parameter definition
1720
- */
1721
- export interface CustomModelInputParam {
1722
- /** Parameter name (used as port ID) */
1723
- name: string;
1724
- /** Parameter type */
1725
- type: CustomModelParamType;
1726
- /** Whether this parameter is required */
1727
- required: boolean;
1728
- /** Description from OpenAPI schema */
1729
- description?: string;
1730
- /** Default value */
1731
- default?: unknown;
1732
- }
1733
- /**
1734
- * Custom Model node configuration - call any fal.ai model
1735
- */
1736
- export interface CustomModelNodeConfig {
1737
- /** fal.ai model ID (e.g., "fal-ai/flux/dev") */
1738
- modelId: string;
1739
- /** Display name for the model */
1740
- modelName: string;
1741
- /** Expected output type (determines how to extract result) */
1742
- outputType: 'image' | 'video' | 'audio';
1743
- /** Dynamic input parameters parsed from OpenAPI schema */
1744
- inputParams: CustomModelInputParam[];
1745
- /** Custom fal.ai API key (optional - uses platform key if not provided) */
1746
- apiKey?: string;
1747
- }
1748
- export interface CanvasState {
1749
- zoom: number;
1750
- panX: number;
1751
- panY: number;
1752
- }
1753
- export interface WorkflowDefinition {
1754
- nodes: WorkflowNodeDefinition[];
1755
- canvasState?: CanvasState;
1756
- }
1757
- /**
1758
- * Template node as stored in the database
1759
- */
1760
- export interface TemplateNode {
1761
- id: string;
1762
- template_id: string;
1763
- node_id: string;
1764
- type: NodeTypeEnum;
1765
- name: string | null;
1766
- x: number;
1767
- y: number;
1768
- inputs: Record<string, {
1769
- sourceNodeId: string;
1770
- sourceOutputId: string;
1771
- }>;
1772
- config: WorkflowNodeDefinition['config'] | null;
1773
- cached_output: Record<string, unknown> | null;
1774
- cached_at: string | null;
1775
- cached_run_id: string | null;
1776
- cached_variable_inputs: Record<string, string> | null;
1777
- preview_outputs: Record<string, string> | null;
1778
- created_at: string;
1779
- updated_at: string;
1780
- }
1781
- export interface AutomationTemplate {
1782
- id: string;
1783
- org_id: string;
1784
- name: string;
1785
- description: string | null;
1786
- canvas_state: CanvasState | null;
1787
- nodes: TemplateNode[];
1788
- preview_output: string | null;
1789
- output_schema: Record<string, {
1790
- type: string;
1791
- }> | null;
1792
- recurrence_enabled: boolean;
1793
- next_run_at: string | null;
1794
- last_run_at: string | null;
1795
- created_at: string;
1796
- updated_at: string;
1797
- }
1798
- export interface AutomationRun {
1799
- id: string;
1800
- template_id: string;
1801
- org_id: string;
1802
- tag: string | null;
1803
- status: 'pending' | 'running' | 'completed' | 'failed';
1804
- variable_inputs: Record<string, string> | null;
1805
- save_as_preview: boolean | null;
1806
- create_post: boolean | null;
1807
- require_review: boolean | null;
1808
- review_status: 'pending_review' | 'approved' | 'rejected' | null;
1809
- created_at: string;
1810
- completed_at: string | null;
1811
- }
1812
- /**
1813
- * @deprecated NodeRun is part of the old execution model.
1814
- * Use ExecutorNode from the new edge-based execution model instead.
1815
- */
1816
- export interface NodeRun {
1817
- id: string;
1818
- automation_run_id: string;
1819
- template_node_id: string;
1820
- type: NodeTypeEnum;
1821
- node_state: 'pending' | 'running' | 'completed' | 'failed';
1822
- input_data: Record<string, unknown> | null;
1823
- output_data: Record<string, unknown> | null;
1824
- created_at: string;
1825
- completed_at: string | null;
1826
- /** Sub-workflow node runs (only present for workflow nodes) */
1827
- subNodes?: NodeRun[];
1828
- }
1829
- /**
1830
- * Executor node from the edge-based execution model.
1831
- * Each executor represents one instance of a template node during execution.
1832
- */
1833
- export interface ExecutorNode {
1834
- id: string;
1835
- template_node_id: string;
1836
- executor_index: number;
1837
- type: NodeTypeEnum;
1838
- status: 'pending' | 'running' | 'completed' | 'failed';
1839
- output_value: unknown | null;
1840
- error_message: string | null;
1841
- created_at: string;
1842
- completed_at: string | null;
1843
- }
1844
- /**
1845
- * Execution edge from the edge-based execution model.
1846
- * Represents a data flow connection between two executors.
1847
- */
1848
- export interface ExecutionEdge {
1849
- id: string;
1850
- source_executor_id: string;
1851
- source_port: string;
1852
- target_executor_id: string;
1853
- target_port: string;
1854
- value: unknown | null;
1855
- }
1856
- /**
1857
- * Media types
1858
- */
1859
- export interface UserMedia {
1860
- id: string;
1861
- org_id: string;
1862
- name: string | null;
1863
- tag: string | null;
1864
- type: 'video' | 'image' | 'audio' | 'text' | null;
1865
- url: string | null;
1866
- preview_url: string | null;
1867
- content: string | null;
1868
- source_id: string | null;
1869
- created_at: string;
1870
- media_type: 'user_media';
1871
- }
1872
- export interface MediaUse {
1873
- id: string;
1874
- user_media_id: string;
1875
- name: string;
1876
- source_id: string | null;
1877
- created_at: string;
1878
- }
1879
- export interface SocialAudio {
1880
- id: string;
1881
- org_id: string;
1882
- name: string | null;
1883
- tag: string | null;
1884
- social_post_link: string | null;
1885
- social_audio_link: string | null;
1886
- platform_type: 'tiktok' | null;
1887
- preview_url: string | null;
1888
- audio_url: string | null;
1889
- created_at: string;
1890
- media_type: 'social_audio';
1891
- type: 'social_audio';
1892
- }
1893
- export type Media = UserMedia | SocialAudio;
1894
- export interface GetMediaParams {
1895
- ids?: string[];
1896
- tag?: string;
1897
- }
1898
- export interface GetSocialAudioParams {
1899
- ids?: string[];
1900
- tag?: string;
1901
- }
1902
- export interface UploadMediaParams {
1903
- files: File[];
1904
- tag?: string;
1905
- }
1906
- export interface UploadMediaResponse {
1907
- data: UserMedia[];
1908
- failed?: Array<{
1909
- name: string;
1910
- error: string;
1911
- }>;
1912
- message: string;
1913
- }
1914
- export interface MediaTagUpdate {
1915
- id: string;
1916
- tag: string;
1917
- }
1918
- export interface UpdateMediaTagsParams {
1919
- updates: MediaTagUpdate[];
1920
- }
1921
- export interface MediaTagUpdateResult {
1922
- id: string;
1923
- success: boolean;
1924
- media?: Media;
1925
- error?: string;
1926
- }
1927
- export interface UpdateMediaTagsResponse {
1928
- results: MediaTagUpdateResult[];
1929
- }
1930
- /**
1931
- * @deprecated Use UpdateMediaTagsParams instead for bulk operations
1932
- */
1933
- export interface UpdateMediaTagParams {
1934
- id: string;
1935
- tag: string;
1936
- }
1937
- export interface DeleteMediaParams {
1938
- ids: string[];
1939
- }
1940
- export interface DeleteMediaResponse {
1941
- deleted: string[];
1942
- failed?: Array<{
1943
- id: string;
1944
- message: string;
1945
- }>;
1946
- message: string;
1947
- }
1948
- export interface CreateSocialAudioParams {
1949
- url: string;
1950
- tag?: string;
1951
- }
1952
- export interface ImportTextParams {
1953
- texts: Array<{
1954
- content: string;
1955
- name?: string;
1956
- tag?: string;
1957
- }>;
1958
- }
1959
- export interface ImportTextResponse {
1960
- data: UserMedia[];
1961
- message: string;
1962
- }
1963
- export interface CreateMediaFromUrlParams {
1964
- urls: string[];
1965
- names?: string[];
1966
- previewUrls?: (string | undefined)[];
1967
- tag?: string;
1968
- sourceIds?: string[];
1969
- useName?: string;
1970
- }
1971
- export interface GetMediaUseParams {
1972
- name: string;
1973
- }
1974
- export interface GetMediaUseResponse {
1975
- sourceIds: string[];
1976
- entries: MediaUse[];
1977
- }
1978
- export interface FilterMediaParams {
1979
- source_ids: string[];
1980
- name: string;
1981
- }
1982
- export interface FilterMediaResponse {
1983
- available: string[];
1984
- used_count: number;
1985
- available_count: number;
1986
- }
1987
- export interface GetUploadTokenParams {
1988
- filename: string;
1989
- contentType?: string;
1990
- }
1991
- export interface UploadTokenResponse {
1992
- clientToken: string;
1993
- pathname: string;
1994
- }
1995
- /**
1996
- * Comment types
1997
- */
1998
- export type CommentStatus = 'scheduled' | 'pending' | 'verifying' | 'completed' | 'failed';
1999
- export interface Comment {
2000
- id: string;
2001
- accountId: string;
2002
- postUrl: string;
2003
- commentText: string;
2004
- status: CommentStatus;
2005
- commentUrl?: string | null;
2006
- error?: string | null;
2007
- createdAt?: string;
2008
- completedAt?: string | null;
2009
- }
2010
- export interface CreateCommentParams {
2011
- accountId: string;
2012
- postUrl: string;
2013
- commentText: string;
2014
- }
2015
- export interface CreateCommentResponse {
2016
- commentId: string;
2017
- }
2018
- export interface GetCommentsParams {
2019
- commentIds?: string[];
2020
- accountIds?: string[];
2021
- tag?: string;
2022
- }
2023
- /**
2024
- * Validation error types for automation workflows
2025
- */
2026
- export type ValidationErrorType = 'missing_trigger' | 'missing_terminal' | 'missing_required_input' | 'type_mismatch' | 'empty_media_pool' | 'empty_account_pool';
2027
- /**
2028
- * Structured validation error with location info for UI highlighting
2029
- */
2030
- export interface ValidationError {
2031
- type: ValidationErrorType;
2032
- nodeId?: string;
2033
- portId?: string;
2034
- message: string;
2035
- }
2036
- /**
2037
- * Exported node representation for debugging
2038
- */
2039
- export interface ExportedNode {
2040
- nodeId: string;
2041
- type: string;
2042
- name: string | null;
2043
- position: {
2044
- x: number;
2045
- y: number;
2046
- };
2047
- inputs: Record<string, {
2048
- sourceNodeId: string;
2049
- sourceOutputId: string;
2050
- }>;
2051
- config: Record<string, unknown>;
2052
- }
2053
- /**
2054
- * Exported connection representation
2055
- */
2056
- export interface ExportedConnection {
2057
- from: {
2058
- nodeId: string;
2059
- port: string;
2060
- };
2061
- to: {
2062
- nodeId: string;
2063
- port: string;
2064
- };
2065
- }
2066
- /**
2067
- * Exported template data
2068
- */
2069
- export interface ExportedTemplate {
2070
- id: string;
2071
- name: string;
2072
- description: string | null;
2073
- canvasState: {
2074
- zoom: number;
2075
- panX: number;
2076
- panY: number;
2077
- } | null;
2078
- outputSchema: Record<string, {
2079
- type: string;
2080
- }> | null;
2081
- createdAt: string;
2082
- updatedAt: string;
2083
- }
2084
- /**
2085
- * Full automation export (template + nodes + connections)
2086
- */
2087
- export interface AutomationExport {
2088
- template: ExportedTemplate;
2089
- nodes: ExportedNode[];
2090
- connections: ExportedConnection[];
2091
- }
2092
- /**
2093
- * Exported executor data
2094
- */
2095
- export interface ExportedExecutor {
2096
- id: string;
2097
- nodeTemplateId: string;
2098
- executorIndex: number;
2099
- type: string;
2100
- status: string;
2101
- outputValue: unknown;
2102
- errorMessage: string | null;
2103
- createdAt: string;
2104
- completedAt: string | null;
2105
- }
2106
- /**
2107
- * Exported edge data
2108
- */
2109
- export interface ExportedEdge {
2110
- sourceExecutorId: string;
2111
- sourceNodeId: string;
2112
- sourcePort: string;
2113
- targetExecutorId: string;
2114
- targetNodeId: string;
2115
- targetPort: string;
2116
- value: unknown;
2117
- }
2118
- /**
2119
- * Exported run data
2120
- */
2121
- export interface ExportedRun {
2122
- id: string;
2123
- templateId: string;
2124
- templateName: string;
2125
- status: string;
2126
- variableInputs: Record<string, string> | null;
2127
- createdAt: string;
2128
- completedAt: string | null;
2129
- }
2130
- /**
2131
- * Full automation run export
2132
- */
2133
- export interface AutomationRunExport {
2134
- run: ExportedRun;
2135
- template: ExportedTemplate;
2136
- nodes: ExportedNode[];
2137
- connections: ExportedConnection[];
2138
- execution: {
2139
- executors: ExportedExecutor[];
2140
- edges: ExportedEdge[];
2141
- };
2142
- }
2143
- /**
2144
- * Account object that flows through edges for posting
2145
- */
2146
- export interface AccountData {
2147
- id: string;
2148
- username: string;
2149
- platform: 'tiktok';
2150
- displayName?: string;
2151
- profilePicUrl?: string;
2152
- metadata?: Record<string, unknown>;
2153
- }
2154
- /**
2155
- * Output structure for flow control nodes (if, random-route).
2156
- * Contains values for selected ports and list of skipped port IDs.
2157
- */
2158
- export interface FlowControlOutput {
2159
- values: Record<string, unknown>;
2160
- skippedPorts: string[];
2161
- }
2162
- /**
2163
- * Node types array for runtime use
2164
- */
2165
- export declare const NodeTypes: readonly ["social-audio", "text", "media", "video-import", "image-composer", "video-composer", "generate-image", "generate-video", "custom-model", "llm", "output", "manual-trigger", "recurrence", "compose-workflow", "account", "auto-post", "save-to-media", "deduplicate", "for-each", "for-each-value", "transcript", "auto-caption", "screenshot-animation", "random", "random-route", "branch", "if", "not", "create-dm", "collect", "destructure"];
2166
- /**
2167
- * Node type enum derived from NodeTypes const array
2168
- * This is the canonical type - use this instead of the string union NodeTypeEnum
2169
- */
2170
- export type NodeType = typeof NodeTypes[number];
2171
- /**
2172
- * Context passed to executor-based node execution.
2173
- * Replaces the complex outputMap/iteration/portOffsets pattern with simple inputs.
2174
- */
2175
- export interface ExecutorContext {
2176
- /** Database ID of this executor */
2177
- executorId: string;
2178
- /** Run ID this executor belongs to */
2179
- runId: string;
2180
- /** Template node ID this executor was created from */
2181
- templateNodeId: string;
2182
- /** Index of this executor (0, 1, 2...) for the same template node */
2183
- executorIndex: number;
2184
- /** Node type */
2185
- type: NodeType;
2186
- /** Node config (includes assignedValue for source nodes) */
2187
- config: Record<string, unknown>;
2188
- /** Input values read from incoming edges (portId -> value) */
2189
- inputs: Record<string, unknown>;
2190
- }
2191
- /**
2192
- * Executor for synchronous nodes.
2193
- * Much simpler than the old NodeControlConfig - just takes context and returns output.
2194
- */
2195
- export interface NodeExecutor<TOutput = unknown> {
2196
- type: NodeType;
2197
- /**
2198
- * Execute the node and return a single output value.
2199
- * For multi-output nodes (like LLM), return an object with output fields.
2200
- */
2201
- execute: (ctx: ExecutorContext) => Promise<TOutput>;
2202
- }
2203
- /**
2204
- * Async job status for executor-based async nodes
2205
- */
2206
- export type ExecutorAsyncJobStatus<TOutput = unknown> = {
2207
- status: 'pending';
2208
- } | {
2209
- status: 'completed';
2210
- output: TOutput;
2211
- } | {
2212
- status: 'failed';
2213
- error: string;
2214
- };
2215
- /**
2216
- * Executor for asynchronous nodes (video-editor, generate-image, workflow).
2217
- * Uses submit/poll pattern for durable workflows.
2218
- */
2219
- export interface AsyncNodeExecutor<TOutput = unknown> extends Omit<NodeExecutor<TOutput>, 'execute'> {
2220
- isAsync: true;
2221
- /** Submit job - returns job ID for polling */
2222
- submitJob: (ctx: ExecutorContext) => Promise<{
2223
- jobId: string;
2224
- }>;
2225
- /** Check job status - called by orchestrator with workflow sleep between calls */
2226
- checkStatus: (jobId: string, ctx: ExecutorContext) => Promise<ExecutorAsyncJobStatus<TOutput>>;
2227
- }
2228
- /**
2229
- * Type guard to check if an executor is async
2230
- */
2231
- export declare function isAsyncExecutor<T>(executor: NodeExecutor<T> | AsyncNodeExecutor<T>): executor is AsyncNodeExecutor<T>;