ugcinc 4.1.0 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automations/nodes/account.d.ts +3 -14
- package/dist/automations/nodes/auto-caption.d.ts +17 -57
- package/dist/automations/nodes/auto-caption.js +15 -11
- package/dist/automations/nodes/auto-post.d.ts +7 -65
- package/dist/automations/nodes/auto-post.js +3 -4
- package/dist/automations/nodes/branch.d.ts +9 -45
- package/dist/automations/nodes/branch.js +0 -3
- package/dist/automations/nodes/collect.d.ts +4 -12
- package/dist/automations/nodes/collect.js +3 -7
- package/dist/automations/nodes/compose-workflow.d.ts +3 -15
- package/dist/automations/nodes/compose-workflow.js +33 -14
- package/dist/automations/nodes/create-dm.d.ts +20 -80
- package/dist/automations/nodes/create-dm.js +28 -30
- package/dist/automations/nodes/custom-model.d.ts +4 -4
- package/dist/automations/nodes/deduplicate.d.ts +2 -2
- package/dist/automations/nodes/destructure.d.ts +4 -3
- package/dist/automations/nodes/destructure.js +1 -1
- package/dist/automations/nodes/for-each.d.ts +2 -2
- package/dist/automations/nodes/generate-image.d.ts +2 -2
- package/dist/automations/nodes/generate-video.d.ts +2 -2
- package/dist/automations/nodes/if.d.ts +2 -2
- package/dist/automations/nodes/image-composer.d.ts +35 -21
- package/dist/automations/nodes/image-composer.js +40 -0
- package/dist/automations/nodes/index.d.ts +299 -7
- package/dist/automations/nodes/index.js +6 -7
- package/dist/automations/nodes/internal.d.ts +8 -0
- package/dist/automations/nodes/internal.js +10 -0
- package/dist/automations/nodes/llm.d.ts +2 -2
- package/dist/automations/nodes/manual-trigger.d.ts +10 -29
- package/dist/automations/nodes/manual-trigger.js +1 -1
- package/dist/automations/nodes/media.d.ts +4 -7
- package/dist/automations/nodes/not.d.ts +2 -2
- package/dist/automations/nodes/output.d.ts +4 -17
- package/dist/automations/nodes/random-route.d.ts +4 -31
- package/dist/automations/nodes/random-route.js +5 -5
- package/dist/automations/nodes/random.d.ts +4 -3
- package/dist/automations/nodes/random.js +3 -3
- package/dist/automations/nodes/recurrence.d.ts +4 -43
- package/dist/automations/nodes/recurrence.js +1 -1
- package/dist/automations/nodes/save-to-media.d.ts +4 -20
- package/dist/automations/nodes/save-to-media.js +1 -1
- package/dist/automations/nodes/screenshot-animation.d.ts +2 -2
- package/dist/automations/nodes/social-audio.d.ts +2 -2
- package/dist/automations/nodes/text.d.ts +2 -2
- package/dist/automations/nodes/transcript.d.ts +2 -2
- package/dist/automations/nodes/types.d.ts +44 -20
- package/dist/automations/nodes/types.js +1 -1
- package/dist/automations/nodes/video-composer.d.ts +2 -10
- package/dist/automations/nodes/video-composer.js +65 -19
- package/dist/automations/nodes/video-import.d.ts +2 -19
- package/dist/automations/nodes/video-import.js +2 -16
- package/dist/automations/types.d.ts +45 -158
- package/dist/automations/types.js +4 -76
- package/dist/graph-controller.d.ts +28 -11
- package/dist/graph-controller.js +53 -20
- package/dist/index.d.ts +37 -22
- package/dist/index.js +9 -2
- package/dist/render/compositions/IMessageDmComposition/types.d.ts +6 -6
- package/dist/render/compositions/ImageEditorComposition.js +2 -8
- package/dist/render/compositions/VideoEditorComposition.js +2 -24
- package/dist/render/types/element.d.ts +0 -33
- package/dist/render/types/index.d.ts +1 -1
- package/dist/render.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Account node configuration - source node for selecting accounts to post from
|
|
3
|
-
*/
|
|
4
|
-
export interface AccountNodeConfig {
|
|
5
|
-
/** List of account IDs to choose from */
|
|
6
|
-
accountIds: string[];
|
|
7
|
-
/** Selection mode */
|
|
8
|
-
selectionConfig?: {
|
|
9
|
-
mode?: 'random' | 'sequential';
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
1
|
declare const definition: import("./types").NodeDefinition<"source", {
|
|
13
|
-
accountIds:
|
|
2
|
+
accountIds: string[];
|
|
14
3
|
outputMode: "per-input";
|
|
15
4
|
selectionMode: "random";
|
|
16
|
-
}>;
|
|
5
|
+
}, false>;
|
|
17
6
|
export default definition;
|
|
18
|
-
export type
|
|
7
|
+
export type AccountNodeConfig = typeof definition.defaults;
|
|
@@ -1,64 +1,24 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto Caption preset styles
|
|
3
|
-
*/
|
|
4
1
|
export type AutoCaptionPreset = 'hormozi' | 'minimal' | 'bold-pop' | 'clean' | 'neon';
|
|
5
|
-
/**
|
|
6
|
-
* Auto Caption font weight options
|
|
7
|
-
*/
|
|
8
2
|
export type AutoCaptionFontWeight = 'normal' | 'bold' | 'black';
|
|
9
|
-
/**
|
|
10
|
-
* Auto Caption position options
|
|
11
|
-
*/
|
|
12
3
|
export type AutoCaptionPosition = 'top' | 'center' | 'bottom';
|
|
13
|
-
/**
|
|
14
|
-
* Auto Caption node configuration - adds TikTok-style captions to videos
|
|
15
|
-
*/
|
|
16
|
-
export interface AutoCaptionNodeConfig {
|
|
17
|
-
/** Preset style (if set, other values are derived from preset) */
|
|
18
|
-
preset?: AutoCaptionPreset;
|
|
19
|
-
/** Google Font name */
|
|
20
|
-
fontName?: string;
|
|
21
|
-
/** Font size in pixels (20-150) */
|
|
22
|
-
fontSize?: number;
|
|
23
|
-
/** Font weight */
|
|
24
|
-
fontWeight?: AutoCaptionFontWeight;
|
|
25
|
-
/** Main text color */
|
|
26
|
-
fontColor?: string;
|
|
27
|
-
/** Highlighted/active word color */
|
|
28
|
-
highlightColor?: string;
|
|
29
|
-
/** Text stroke/outline color */
|
|
30
|
-
strokeColor?: string;
|
|
31
|
-
/** Stroke width in pixels (0-10) */
|
|
32
|
-
strokeWidth?: number;
|
|
33
|
-
/** Background color behind text */
|
|
34
|
-
backgroundColor?: string;
|
|
35
|
-
/** Vertical position */
|
|
36
|
-
position?: AutoCaptionPosition;
|
|
37
|
-
/** Vertical offset in pixels from position anchor */
|
|
38
|
-
yOffset?: number;
|
|
39
|
-
/** Maximum width as percentage of video width (0-100) */
|
|
40
|
-
maxWidth?: number;
|
|
41
|
-
/** Words per subtitle segment (1-12) */
|
|
42
|
-
wordsPerSubtitle?: number;
|
|
43
|
-
/** Enable bounce animation effect */
|
|
44
|
-
enableAnimation?: boolean;
|
|
45
|
-
/** Language code for transcription */
|
|
46
|
-
language?: string;
|
|
47
|
-
}
|
|
48
4
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
5
|
+
preset: AutoCaptionPreset;
|
|
6
|
+
fontName: string | undefined;
|
|
7
|
+
fontSize: number | undefined;
|
|
8
|
+
fontWeight: AutoCaptionFontWeight | undefined;
|
|
9
|
+
fontColor: string | undefined;
|
|
10
|
+
highlightColor: string | undefined;
|
|
11
|
+
strokeColor: string | undefined;
|
|
12
|
+
strokeWidth: number | undefined;
|
|
13
|
+
backgroundColor: string | undefined;
|
|
14
|
+
position: AutoCaptionPosition | undefined;
|
|
15
|
+
yOffset: number | undefined;
|
|
16
|
+
maxWidth: number | undefined;
|
|
17
|
+
wordsPerSubtitle: number | undefined;
|
|
18
|
+
enableAnimation: boolean | undefined;
|
|
19
|
+
language: string | undefined;
|
|
60
20
|
outputMode: "per-input";
|
|
61
21
|
selectionMode: null;
|
|
62
|
-
}>;
|
|
22
|
+
}, false>;
|
|
63
23
|
export default definition;
|
|
64
|
-
export type
|
|
24
|
+
export type AutoCaptionNodeConfig = typeof definition.defaults;
|
|
@@ -10,17 +10,21 @@ const definition = (0, types_1.defineNode)({
|
|
|
10
10
|
outputModes: ['per-input', 'single'],
|
|
11
11
|
selectionModes: null,
|
|
12
12
|
defaults: {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
preset: 'hormozi',
|
|
14
|
+
fontName: undefined,
|
|
15
|
+
fontSize: undefined,
|
|
16
|
+
fontWeight: undefined,
|
|
17
|
+
fontColor: undefined,
|
|
18
|
+
highlightColor: undefined,
|
|
19
|
+
strokeColor: undefined,
|
|
20
|
+
strokeWidth: undefined,
|
|
21
|
+
backgroundColor: undefined,
|
|
22
|
+
position: undefined,
|
|
23
|
+
yOffset: undefined,
|
|
24
|
+
maxWidth: undefined,
|
|
25
|
+
wordsPerSubtitle: undefined,
|
|
26
|
+
enableAnimation: undefined,
|
|
27
|
+
language: undefined,
|
|
24
28
|
outputMode: 'per-input',
|
|
25
29
|
selectionMode: null,
|
|
26
30
|
},
|
|
@@ -1,73 +1,15 @@
|
|
|
1
|
-
import type
|
|
2
|
-
/**
|
|
3
|
-
* Scheduling mode for post nodes
|
|
4
|
-
* - 'scheduled': Post immediately when automation runs
|
|
5
|
-
* - 'queue': Automatically schedule based on queue constraints
|
|
6
|
-
*/
|
|
7
|
-
export type PostSchedulingMode = 'scheduled' | 'queue';
|
|
8
|
-
/**
|
|
9
|
-
* Post scheduling configuration for post nodes
|
|
10
|
-
*/
|
|
11
|
-
export interface PostSchedulingConfig {
|
|
12
|
-
/** Main scheduling mode ('scheduled' = post now, 'queue' = auto-schedule) */
|
|
13
|
-
mode: PostSchedulingMode;
|
|
14
|
-
/** Minimum hours between posts for this account (min 1) */
|
|
15
|
-
minDistanceHours?: number;
|
|
16
|
-
/** Maximum posts per day for this account (min 1) */
|
|
17
|
-
maxPostsPerDay?: number;
|
|
18
|
-
/** Minimum time of day for posting (HH:mm format, e.g., '09:00') */
|
|
19
|
-
randomWindowStart?: string;
|
|
20
|
-
/** Maximum time of day for posting (HH:mm format, e.g., '21:00') */
|
|
21
|
-
randomWindowEnd?: string;
|
|
22
|
-
/** Timezone for time window (IANA timezone, e.g., 'America/New_York') */
|
|
23
|
-
timezone?: string;
|
|
24
|
-
/** If true, post will be created with 'require-approval' status instead of being posted */
|
|
25
|
-
requireApproval?: boolean;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Auto Post mode - video or slideshow
|
|
29
|
-
*/
|
|
1
|
+
import { type InputType } from './types';
|
|
30
2
|
export type AutoPostMode = 'video' | 'slideshow';
|
|
31
|
-
|
|
32
|
-
* Auto Post input type for slideshow mode
|
|
33
|
-
* - 'static': Individual image input ports (image1, image2, etc.)
|
|
34
|
-
* - 'variable': Single 'images' port accepting an array
|
|
35
|
-
*/
|
|
36
|
-
export type AutoPostInputType = 'static' | 'variable';
|
|
37
|
-
/**
|
|
38
|
-
* Auto Post input definition (for slideshow static mode)
|
|
39
|
-
*/
|
|
40
|
-
export interface AutoPostInput {
|
|
41
|
-
id: string;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Auto Post node configuration - posts a video or slideshow to social media
|
|
45
|
-
*/
|
|
46
|
-
export interface AutoPostNodeConfig {
|
|
47
|
-
/** Post mode - video or slideshow */
|
|
48
|
-
mode: AutoPostMode;
|
|
49
|
-
/** Input type for slideshow mode (defaults to 'static') */
|
|
50
|
-
inputType?: AutoPostInputType;
|
|
51
|
-
/** Dynamic image inputs (only used in slideshow mode with inputType='static') */
|
|
52
|
-
inputs?: AutoPostInput[];
|
|
53
|
-
/** Scheduling configuration */
|
|
54
|
-
scheduling?: PostSchedulingConfig;
|
|
55
|
-
/** Social audio configuration */
|
|
56
|
-
socialAudio?: {
|
|
57
|
-
/** If true, read from input port; if false, use selectedIds */
|
|
58
|
-
isVariable: boolean;
|
|
59
|
-
/** Selected social audio IDs (when isVariable is false) - one is randomly chosen when posting */
|
|
60
|
-
selectedIds?: string[];
|
|
61
|
-
};
|
|
62
|
-
}
|
|
3
|
+
export type PostSchedulingMode = 'scheduled' | 'queue';
|
|
63
4
|
declare const definition: import("./types").NodeDefinition<"terminal", {
|
|
64
5
|
mode: AutoPostMode;
|
|
65
6
|
inputType: InputType;
|
|
66
|
-
|
|
7
|
+
imageInputs: Array<{
|
|
67
8
|
id: string;
|
|
68
9
|
}>;
|
|
69
10
|
socialAudioIsVariable: boolean;
|
|
70
|
-
|
|
11
|
+
socialAudioSelectedIds: string[];
|
|
12
|
+
schedulingMode: PostSchedulingMode;
|
|
71
13
|
minDistanceHours: number;
|
|
72
14
|
maxPostsPerDay: number;
|
|
73
15
|
randomWindowStart: string;
|
|
@@ -76,6 +18,6 @@ declare const definition: import("./types").NodeDefinition<"terminal", {
|
|
|
76
18
|
requireApproval: boolean;
|
|
77
19
|
outputMode: null;
|
|
78
20
|
selectionMode: null;
|
|
79
|
-
}>;
|
|
21
|
+
}, false>;
|
|
80
22
|
export default definition;
|
|
81
|
-
export type
|
|
23
|
+
export type AutoPostNodeConfig = typeof definition.defaults;
|
|
@@ -12,8 +12,9 @@ const definition = (0, types_1.defineNode)({
|
|
|
12
12
|
defaults: {
|
|
13
13
|
mode: 'video',
|
|
14
14
|
inputType: 'static',
|
|
15
|
-
|
|
15
|
+
imageInputs: [],
|
|
16
16
|
socialAudioIsVariable: false,
|
|
17
|
+
socialAudioSelectedIds: [],
|
|
17
18
|
schedulingMode: 'scheduled',
|
|
18
19
|
minDistanceHours: 4,
|
|
19
20
|
maxPostsPerDay: 3,
|
|
@@ -36,15 +37,13 @@ const definition = (0, types_1.defineNode)({
|
|
|
36
37
|
inputs.push({ id: 'images', type: 'object', isArray: false, required: true });
|
|
37
38
|
}
|
|
38
39
|
else {
|
|
39
|
-
const imageInputs = config?.
|
|
40
|
+
const imageInputs = config?.imageInputs ?? [{ id: 'image1' }, { id: 'image2' }, { id: 'image3' }];
|
|
40
41
|
for (const input of imageInputs) {
|
|
41
42
|
inputs.push({ id: input.id, type: 'image', isArray: false, required: true });
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
// Static inputs for both modes
|
|
46
46
|
inputs.push({ id: 'account', type: 'account', isArray: false, required: true }, { id: 'caption', type: 'text', isArray: false, required: false });
|
|
47
|
-
// Social audio variable input
|
|
48
47
|
if (config?.socialAudioIsVariable) {
|
|
49
48
|
inputs.push({ id: 'social-audio', type: 'audio', isArray: false, required: false });
|
|
50
49
|
}
|
|
@@ -1,58 +1,22 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { PassthroughInput } from './types';
|
|
3
|
-
import type { RandomRouteObjectField } from './random-route';
|
|
4
|
-
/**
|
|
5
|
-
* Branch node branch definition
|
|
6
|
-
*/
|
|
1
|
+
import { type InputType } from './types';
|
|
7
2
|
export interface BranchDefinition {
|
|
8
|
-
/** The key to match against (e.g., "happy", "sad", "neutral") */
|
|
9
3
|
key: string;
|
|
10
4
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
isVariable: true;
|
|
16
|
-
} | {
|
|
17
|
-
isVariable: false;
|
|
18
|
-
value: unknown;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Branch node passthrough input definition
|
|
22
|
-
*/
|
|
23
|
-
export interface BranchPassthroughInput {
|
|
24
|
-
/** The input port ID (lowercase, hyphens/underscores only) */
|
|
5
|
+
interface BranchValueConfig {
|
|
6
|
+
inputType?: InputType;
|
|
7
|
+
}
|
|
8
|
+
export interface PassthroughInput {
|
|
25
9
|
id: string;
|
|
26
|
-
|
|
27
|
-
type: 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'account' | 'object';
|
|
28
|
-
/** Whether this is an array type */
|
|
10
|
+
type: string;
|
|
29
11
|
isArray?: boolean;
|
|
30
|
-
/** Per-branch value configuration. Key is branch key. Each branch can be variable (input port) or static (value). */
|
|
31
12
|
branchValues?: Record<string, BranchValueConfig>;
|
|
32
|
-
/** Object schema for object type (when type is 'object') */
|
|
33
|
-
objectSchema?: RandomRouteObjectField[];
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Branch node configuration - routes inputs to a branch based on key match
|
|
37
|
-
*/
|
|
38
|
-
export interface BranchNodeConfig {
|
|
39
|
-
/** Output branches with keys to match against */
|
|
40
|
-
branches: BranchDefinition[];
|
|
41
|
-
/** Passthrough inputs that get routed to the matched branch's outputs */
|
|
42
|
-
passthroughInputs: BranchPassthroughInput[];
|
|
43
|
-
/** Optional default branch key if no match is found */
|
|
44
|
-
defaultBranchKey?: string;
|
|
45
|
-
/** Output mode - 'single' broadcasts one output to all consumers, 'per-input' creates one per consumer */
|
|
46
|
-
outputMode?: OutputMode;
|
|
47
13
|
}
|
|
48
14
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
49
|
-
branches:
|
|
50
|
-
key: string;
|
|
51
|
-
}[];
|
|
15
|
+
branches: BranchDefinition[];
|
|
52
16
|
passthroughInputs: PassthroughInput[];
|
|
53
17
|
defaultBranchKey: string;
|
|
54
18
|
outputMode: "per-input";
|
|
55
19
|
selectionMode: null;
|
|
56
|
-
}>;
|
|
20
|
+
}, false>;
|
|
57
21
|
export default definition;
|
|
58
|
-
export type
|
|
22
|
+
export type BranchNodeConfig = typeof definition.defaults;
|
|
@@ -24,9 +24,7 @@ const definition = (0, types_1.defineNode)({
|
|
|
24
24
|
const passthroughInputs = config?.passthroughInputs ?? [];
|
|
25
25
|
const inputs = [];
|
|
26
26
|
const outputs = [];
|
|
27
|
-
// Always add key input for branch selection
|
|
28
27
|
inputs.push({ id: 'key', type: 'text', isArray: false, required: true });
|
|
29
|
-
// Add input ports for each branch × passthrough where isVariable is true
|
|
30
28
|
for (const passthrough of passthroughInputs) {
|
|
31
29
|
const pType = passthrough.type;
|
|
32
30
|
const pIsArray = passthrough.isArray ?? false;
|
|
@@ -41,7 +39,6 @@ const definition = (0, types_1.defineNode)({
|
|
|
41
39
|
});
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
// One output per passthrough
|
|
45
42
|
outputs.push({ id: passthrough.id, type: pType, isArray: pIsArray, required: true });
|
|
46
43
|
}
|
|
47
44
|
return { inputs, outputs };
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
2
|
+
expectedCount: number | undefined;
|
|
3
|
+
forEachTemplateId: string | undefined;
|
|
2
4
|
outputMode: "single";
|
|
3
5
|
selectionMode: null;
|
|
4
|
-
}>;
|
|
6
|
+
}, false>;
|
|
5
7
|
export default definition;
|
|
6
|
-
export type
|
|
7
|
-
/**
|
|
8
|
-
* Collect node configuration - collects outputs from for-each loop into an array
|
|
9
|
-
* Note: Most config is set during expansion, not by user
|
|
10
|
-
*/
|
|
11
|
-
export interface CollectNodeConfig {
|
|
12
|
-
/** Expected number of items to collect (set during for-each expansion) */
|
|
13
|
-
expectedCount?: number;
|
|
14
|
-
/** Template ID of the for-each loop this collects from (for validation) */
|
|
15
|
-
forEachTemplateId?: string;
|
|
16
|
-
}
|
|
8
|
+
export type CollectNodeConfig = typeof definition.defaults;
|
|
@@ -10,28 +10,24 @@ const definition = (0, types_1.defineNode)({
|
|
|
10
10
|
outputModes: ['per-input', 'single'],
|
|
11
11
|
selectionModes: null,
|
|
12
12
|
defaults: {
|
|
13
|
-
|
|
13
|
+
expectedCount: undefined,
|
|
14
|
+
forEachTemplateId: undefined,
|
|
15
|
+
outputMode: 'single',
|
|
14
16
|
selectionMode: null,
|
|
15
17
|
},
|
|
16
18
|
computePorts: ({ getConnectedOutput }) => {
|
|
17
|
-
// Input: accepts any non-array type (union)
|
|
18
19
|
const inputTypes = ['image', 'video', 'audio', 'text', 'object', 'boolean', 'number'];
|
|
19
|
-
// Default output: union of all types (will be array)
|
|
20
20
|
const defaultOutputTypes = ['image', 'video', 'audio', 'text', 'object'];
|
|
21
|
-
// Determine output type from connected input (inverse of for-each pattern)
|
|
22
21
|
let outputType = defaultOutputTypes;
|
|
23
22
|
let outputIsArray = true;
|
|
24
23
|
if (getConnectedOutput) {
|
|
25
24
|
const connectedOutput = getConnectedOutput('value');
|
|
26
25
|
if (connectedOutput?.type) {
|
|
27
26
|
const connType = connectedOutput.type;
|
|
28
|
-
// Handle single type (not a union)
|
|
29
27
|
if (!Array.isArray(connType) && !connectedOutput.isArray) {
|
|
30
|
-
// If connected to a non-array type, output is an array of that type
|
|
31
28
|
outputType = connType;
|
|
32
29
|
outputIsArray = true;
|
|
33
30
|
}
|
|
34
|
-
// If connected to a union type, can't narrow - keep default union
|
|
35
31
|
}
|
|
36
32
|
}
|
|
37
33
|
const inputs = [
|
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import type { ResolvedPorts
|
|
2
|
-
import { type ObjectSchemaField } from './types';
|
|
1
|
+
import type { ResolvedPorts } from '../types';
|
|
3
2
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
4
3
|
workflowTemplateId: string | undefined;
|
|
5
|
-
workflowVariableNodes: Array<{
|
|
6
|
-
id: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
variableType?: "image" | "video" | "audio" | "text" | "enum";
|
|
9
|
-
enumOptions?: EnumOption[];
|
|
10
|
-
}>;
|
|
11
|
-
workflowOutputSchema: Record<string, {
|
|
12
|
-
type: string;
|
|
13
|
-
isArray?: boolean;
|
|
14
|
-
objectSchema?: ObjectSchemaField[];
|
|
15
|
-
}>;
|
|
16
4
|
resolvedPorts: ResolvedPorts | undefined;
|
|
17
5
|
outputMode: "per-input";
|
|
18
6
|
selectionMode: null;
|
|
19
|
-
}>;
|
|
7
|
+
}, false>;
|
|
20
8
|
export default definition;
|
|
21
|
-
export type
|
|
9
|
+
export type ComposeWorkflowNodeConfig = typeof definition.defaults;
|
|
@@ -11,30 +11,49 @@ const definition = (0, types_1.defineNode)({
|
|
|
11
11
|
selectionModes: null,
|
|
12
12
|
defaults: {
|
|
13
13
|
workflowTemplateId: undefined,
|
|
14
|
-
workflowVariableNodes: [],
|
|
15
|
-
workflowOutputSchema: {},
|
|
16
14
|
resolvedPorts: undefined,
|
|
17
15
|
outputMode: 'per-input',
|
|
18
16
|
selectionMode: null,
|
|
19
17
|
},
|
|
20
|
-
computePorts: ({ config }) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
computePorts: async ({ config, client }) => {
|
|
19
|
+
// Use cached resolved ports if available
|
|
20
|
+
if (config?.resolvedPorts) {
|
|
21
|
+
return {
|
|
22
|
+
inputs: config.resolvedPorts.inputs ?? [],
|
|
23
|
+
outputs: config.resolvedPorts.outputs ?? [],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// If no templateId selected, return empty ports
|
|
27
|
+
const templateId = config?.workflowTemplateId;
|
|
28
|
+
if (!templateId || !client) {
|
|
29
|
+
return { inputs: [], outputs: [] };
|
|
30
|
+
}
|
|
31
|
+
// Fetch the sub-workflow template
|
|
32
|
+
const response = await client.getTemplate({ templateId });
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
return { inputs: [], outputs: [] };
|
|
35
|
+
}
|
|
36
|
+
const template = response.data;
|
|
37
|
+
// Find the manual-trigger node to get input definitions
|
|
38
|
+
const manualTrigger = template.nodes.find(n => n.type === 'manual-trigger');
|
|
39
|
+
const triggerOutputs = manualTrigger?.type === 'manual-trigger'
|
|
40
|
+
? (manualTrigger.config?.outputs ?? [])
|
|
41
|
+
: [];
|
|
42
|
+
// Convert trigger outputs to compose-workflow inputs
|
|
43
|
+
const inputs = triggerOutputs.map(output => ({
|
|
44
|
+
id: output.id,
|
|
45
|
+
type: output.type,
|
|
46
|
+
isArray: output.isArray ?? false,
|
|
28
47
|
required: true,
|
|
29
|
-
...(
|
|
48
|
+
...(output.type === 'enum' && output.enumOptions ? { enumOptions: output.enumOptions } : {}),
|
|
30
49
|
}));
|
|
31
|
-
//
|
|
50
|
+
// Use template's output_schema for outputs
|
|
51
|
+
const outputSchema = template.output_schema ?? {};
|
|
32
52
|
const outputs = Object.entries(outputSchema).map(([id, schema]) => ({
|
|
33
53
|
id,
|
|
34
54
|
type: schema.type,
|
|
35
|
-
isArray:
|
|
55
|
+
isArray: false,
|
|
36
56
|
required: true,
|
|
37
|
-
...(schema.objectSchema && { objectSchema: schema.objectSchema }),
|
|
38
57
|
}));
|
|
39
58
|
return { inputs, outputs };
|
|
40
59
|
},
|
|
@@ -1,96 +1,36 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
3
|
-
* Message in a Create DM conversation
|
|
4
|
-
*/
|
|
1
|
+
import { type InputType } from './types';
|
|
2
|
+
export type DmPlatform = 'imessage' | 'instagram';
|
|
5
3
|
export interface CreateDmMessage {
|
|
6
|
-
/** Who sent this message */
|
|
7
4
|
sender: 'user' | 'recipient';
|
|
8
|
-
/** Message text content */
|
|
9
5
|
text: string;
|
|
10
|
-
/** Whether this message has an associated image (story reply for IG, sender image for iMessage) */
|
|
11
6
|
hasImage?: boolean;
|
|
12
7
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Create DM node configuration - renders fake DM conversations for iMessage or Instagram
|
|
15
|
-
*/
|
|
16
|
-
export interface CreateDmNodeConfig {
|
|
17
|
-
/** Platform to render */
|
|
18
|
-
platform: 'imessage' | 'instagram';
|
|
19
|
-
/** Whether platform comes from input port */
|
|
20
|
-
platformIsVariable?: boolean;
|
|
21
|
-
/** Light or dark mode */
|
|
22
|
-
lightMode: boolean;
|
|
23
|
-
/** Whether light mode comes from input port */
|
|
24
|
-
lightModeIsVariable?: boolean;
|
|
25
|
-
/** Username displayed in header */
|
|
26
|
-
username: string;
|
|
27
|
-
/** Whether username comes from input port */
|
|
28
|
-
usernameIsVariable?: boolean;
|
|
29
|
-
/** Status bar time */
|
|
30
|
-
time: string;
|
|
31
|
-
/** Whether status bar time comes from input port */
|
|
32
|
-
timeIsVariable?: boolean;
|
|
33
|
-
/** Profile picture URL (fallback if profilePic input not connected) */
|
|
34
|
-
profilePicUrl?: string;
|
|
35
|
-
/** Whether profile pic comes from input port */
|
|
36
|
-
profilePicIsVariable?: boolean;
|
|
37
|
-
/** Whether messages come from input port */
|
|
38
|
-
messagesIsVariable?: boolean;
|
|
39
|
-
/** Static messages (used when messagesIsVariable is false) */
|
|
40
|
-
messages?: CreateDmMessage[];
|
|
41
|
-
/** Image attachment URL (story reply for IG, sender image for iMessage) */
|
|
42
|
-
imageAttachmentUrl?: string;
|
|
43
|
-
/** Whether image attachment comes from input port */
|
|
44
|
-
imageAttachmentIsVariable?: boolean;
|
|
45
|
-
/** iMessage-specific settings */
|
|
46
|
-
imessage?: {
|
|
47
|
-
senderBubbleColor?: string;
|
|
48
|
-
showReadReceipt: boolean;
|
|
49
|
-
readReceiptText: string;
|
|
50
|
-
/** Whether read receipt time comes from input port */
|
|
51
|
-
readReceiptTimeIsVariable?: boolean;
|
|
52
|
-
unreadBadgeText: string;
|
|
53
|
-
/** Whether unread badge comes from input port */
|
|
54
|
-
unreadBadgeIsVariable?: boolean;
|
|
55
|
-
messageHeaderTimestampText: string;
|
|
56
|
-
/** Whether message header time comes from input port */
|
|
57
|
-
messageHeaderTimeIsVariable?: boolean;
|
|
58
|
-
};
|
|
59
|
-
/** Instagram-specific settings */
|
|
60
|
-
instagram?: {
|
|
61
|
-
userHasStory: boolean;
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
8
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
65
9
|
platform: DmPlatform;
|
|
66
|
-
|
|
10
|
+
platformInputType: InputType;
|
|
67
11
|
lightMode: boolean;
|
|
68
|
-
|
|
12
|
+
lightModeInputType: InputType;
|
|
69
13
|
username: string;
|
|
70
|
-
|
|
14
|
+
usernameInputType: InputType;
|
|
71
15
|
time: string;
|
|
72
|
-
|
|
16
|
+
timeInputType: InputType;
|
|
73
17
|
profilePicUrl: string;
|
|
74
|
-
|
|
75
|
-
messagesIsVariable: boolean;
|
|
18
|
+
profilePicInputType: InputType;
|
|
76
19
|
messages: CreateDmMessage[];
|
|
20
|
+
messagesInputType: InputType;
|
|
77
21
|
imageAttachmentUrl: string | undefined;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
instagram: {
|
|
90
|
-
userHasStory: boolean;
|
|
91
|
-
};
|
|
22
|
+
imageAttachmentInputType: InputType;
|
|
23
|
+
imessageSenderBubbleColor: string | undefined;
|
|
24
|
+
imessageShowReadReceipt: boolean;
|
|
25
|
+
imessageReadReceiptText: string;
|
|
26
|
+
imessageReadReceiptTimeInputType: InputType;
|
|
27
|
+
imessageUnreadBadgeText: string;
|
|
28
|
+
imessageUnreadBadgeInputType: InputType;
|
|
29
|
+
imessageMessageHeaderTimestampText: string;
|
|
30
|
+
imessageMessageHeaderTimeInputType: InputType;
|
|
31
|
+
instagramUserHasStory: boolean;
|
|
92
32
|
outputMode: "per-input";
|
|
93
33
|
selectionMode: null;
|
|
94
|
-
}>;
|
|
34
|
+
}, false>;
|
|
95
35
|
export default definition;
|
|
96
|
-
export type
|
|
36
|
+
export type CreateDmNodeConfig = typeof definition.defaults;
|