ugcinc 4.1.0 → 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.
- package/dist/automations/nodes/account.d.ts +3 -15
- package/dist/automations/nodes/account.js +1 -2
- package/dist/automations/nodes/auto-caption.d.ts +21 -62
- package/dist/automations/nodes/auto-caption.js +16 -13
- package/dist/automations/nodes/auto-post.d.ts +9 -68
- package/dist/automations/nodes/auto-post.js +4 -6
- package/dist/automations/nodes/branch.d.ts +9 -46
- package/dist/automations/nodes/branch.js +1 -5
- package/dist/automations/nodes/collect.d.ts +5 -14
- package/dist/automations/nodes/collect.js +4 -9
- package/dist/automations/nodes/compose-workflow.d.ts +2 -15
- package/dist/automations/nodes/compose-workflow.js +33 -14
- package/dist/automations/nodes/create-dm.d.ts +18 -79
- package/dist/automations/nodes/create-dm.js +28 -30
- package/dist/automations/nodes/custom-model.d.ts +3 -4
- package/dist/automations/nodes/deduplicate.d.ts +1 -2
- package/dist/automations/nodes/destructure.d.ts +3 -3
- package/dist/automations/nodes/destructure.js +1 -1
- package/dist/automations/nodes/for-each.d.ts +1 -2
- package/dist/automations/nodes/generate-image.d.ts +1 -2
- package/dist/automations/nodes/generate-video.d.ts +1 -2
- package/dist/automations/nodes/if.d.ts +1 -2
- package/dist/automations/nodes/image-composer.d.ts +34 -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 +1 -2
- package/dist/automations/nodes/manual-trigger.d.ts +9 -29
- package/dist/automations/nodes/manual-trigger.js +1 -1
- package/dist/automations/nodes/media.d.ts +3 -7
- package/dist/automations/nodes/not.d.ts +1 -2
- package/dist/automations/nodes/output.d.ts +3 -17
- package/dist/automations/nodes/random-route.d.ts +3 -31
- package/dist/automations/nodes/random-route.js +5 -5
- package/dist/automations/nodes/random.d.ts +3 -3
- package/dist/automations/nodes/random.js +3 -3
- package/dist/automations/nodes/recurrence.d.ts +3 -43
- package/dist/automations/nodes/recurrence.js +1 -1
- package/dist/automations/nodes/save-to-media.d.ts +3 -20
- package/dist/automations/nodes/save-to-media.js +1 -1
- package/dist/automations/nodes/screenshot-animation.d.ts +1 -2
- package/dist/automations/nodes/social-audio.d.ts +1 -2
- package/dist/automations/nodes/text.d.ts +1 -2
- package/dist/automations/nodes/transcript.d.ts +1 -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 +1 -10
- package/dist/automations/nodes/video-composer.js +65 -19
- package/dist/automations/nodes/video-import.d.ts +1 -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 +7 -23
- package/dist/index.js +5 -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,6 @@
|
|
|
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 */
|
|
1
|
+
declare const _default: import("./types").NodeDefinition<"source", {
|
|
6
2
|
accountIds: string[];
|
|
7
|
-
/** Selection mode */
|
|
8
|
-
selectionConfig?: {
|
|
9
|
-
mode?: 'random' | 'sequential';
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
declare const definition: import("./types").NodeDefinition<"source", {
|
|
13
|
-
accountIds: never[];
|
|
14
3
|
outputMode: "per-input";
|
|
15
4
|
selectionMode: "random";
|
|
16
|
-
}>;
|
|
17
|
-
export default
|
|
18
|
-
export type AccountConfig = typeof definition.defaults;
|
|
5
|
+
}, false>;
|
|
6
|
+
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const types_1 = require("./types");
|
|
4
|
-
|
|
4
|
+
exports.default = (0, types_1.defineNode)({
|
|
5
5
|
nodeId: 'account',
|
|
6
6
|
label: 'Account',
|
|
7
7
|
description: 'Select accounts to post from',
|
|
@@ -26,4 +26,3 @@ const definition = (0, types_1.defineNode)({
|
|
|
26
26
|
],
|
|
27
27
|
}),
|
|
28
28
|
});
|
|
29
|
-
exports.default = definition;
|
|
@@ -1,64 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
49
|
-
fontName: string;
|
|
50
|
-
fontSize: number;
|
|
51
|
-
fontWeight: string;
|
|
52
|
-
fontColor: string;
|
|
53
|
-
highlightColor: string;
|
|
54
|
-
strokeColor: string;
|
|
55
|
-
strokeWidth: number;
|
|
56
|
-
position: string;
|
|
57
|
-
wordsPerSubtitle: number;
|
|
58
|
-
enableAnimation: boolean;
|
|
59
|
-
language: string;
|
|
1
|
+
type AutoCaptionPreset = 'hormozi' | 'minimal' | 'bold-pop' | 'clean' | 'neon';
|
|
2
|
+
type AutoCaptionFontWeight = 'normal' | 'bold' | 'black';
|
|
3
|
+
type AutoCaptionPosition = 'top' | 'center' | 'bottom';
|
|
4
|
+
declare const _default: import("./types").NodeDefinition<"generator", {
|
|
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
|
-
}>;
|
|
63
|
-
export default
|
|
64
|
-
export type AutoCaptionConfig = typeof definition.defaults;
|
|
22
|
+
}, false>;
|
|
23
|
+
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const types_1 = require("./types");
|
|
4
|
-
|
|
4
|
+
exports.default = (0, types_1.defineNode)({
|
|
5
5
|
nodeId: 'auto-caption',
|
|
6
6
|
label: 'Auto Caption',
|
|
7
7
|
description: 'Add TikTok-style captions to videos',
|
|
@@ -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
|
},
|
|
@@ -43,4 +47,3 @@ const definition = (0, types_1.defineNode)({
|
|
|
43
47
|
],
|
|
44
48
|
}),
|
|
45
49
|
});
|
|
46
|
-
exports.default = definition;
|
|
@@ -1,73 +1,15 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
*/
|
|
30
|
-
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
|
-
}
|
|
63
|
-
declare const definition: import("./types").NodeDefinition<"terminal", {
|
|
1
|
+
import { type InputType } from './types';
|
|
2
|
+
type AutoPostMode = 'video' | 'slideshow';
|
|
3
|
+
type PostSchedulingMode = 'scheduled' | 'queue';
|
|
4
|
+
declare const _default: 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,5 @@ declare const definition: import("./types").NodeDefinition<"terminal", {
|
|
|
76
18
|
requireApproval: boolean;
|
|
77
19
|
outputMode: null;
|
|
78
20
|
selectionMode: null;
|
|
79
|
-
}>;
|
|
80
|
-
export default
|
|
81
|
-
export type AutoPostConfig = typeof definition.defaults;
|
|
21
|
+
}, false>;
|
|
22
|
+
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const types_1 = require("./types");
|
|
4
|
-
|
|
4
|
+
exports.default = (0, types_1.defineNode)({
|
|
5
5
|
nodeId: 'auto-post',
|
|
6
6
|
label: 'Auto Post',
|
|
7
7
|
description: 'Publish a video or slideshow',
|
|
@@ -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,19 +37,16 @@ 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
|
}
|
|
51
50
|
return { inputs, outputs: [] };
|
|
52
51
|
},
|
|
53
52
|
});
|
|
54
|
-
exports.default = definition;
|
|
@@ -1,58 +1,21 @@
|
|
|
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
13
|
}
|
|
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 */
|
|
14
|
+
declare const _default: import("./types").NodeDefinition<"generator", {
|
|
40
15
|
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
|
-
}
|
|
48
|
-
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
49
|
-
branches: {
|
|
50
|
-
key: string;
|
|
51
|
-
}[];
|
|
52
16
|
passthroughInputs: PassthroughInput[];
|
|
53
17
|
defaultBranchKey: string;
|
|
54
18
|
outputMode: "per-input";
|
|
55
19
|
selectionMode: null;
|
|
56
|
-
}>;
|
|
57
|
-
export default
|
|
58
|
-
export type BranchConfig = typeof definition.defaults;
|
|
20
|
+
}, false>;
|
|
21
|
+
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const types_1 = require("./types");
|
|
4
|
-
|
|
4
|
+
exports.default = (0, types_1.defineNode)({
|
|
5
5
|
nodeId: 'branch',
|
|
6
6
|
label: 'Branch',
|
|
7
7
|
description: 'Route inputs based on a key match',
|
|
@@ -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,10 +39,8 @@ 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 };
|
|
48
45
|
},
|
|
49
46
|
});
|
|
50
|
-
exports.default = definition;
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
declare const
|
|
1
|
+
declare const _default: import("./types").NodeDefinition<"generator", {
|
|
2
|
+
expectedCount: number | undefined;
|
|
3
|
+
forEachTemplateId: string | undefined;
|
|
2
4
|
outputMode: "single";
|
|
3
5
|
selectionMode: null;
|
|
4
|
-
}>;
|
|
5
|
-
export default
|
|
6
|
-
export type CollectConfig = typeof definition.defaults;
|
|
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
|
-
}
|
|
6
|
+
}, false>;
|
|
7
|
+
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const types_1 = require("./types");
|
|
4
|
-
|
|
4
|
+
exports.default = (0, types_1.defineNode)({
|
|
5
5
|
nodeId: 'collect',
|
|
6
6
|
label: 'Collect',
|
|
7
7
|
description: 'Collect outputs from a for-each loop into an array',
|
|
@@ -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 = [
|
|
@@ -53,4 +49,3 @@ const definition = (0, types_1.defineNode)({
|
|
|
53
49
|
return { inputs, outputs };
|
|
54
50
|
},
|
|
55
51
|
});
|
|
56
|
-
exports.default = definition;
|
|
@@ -1,21 +1,8 @@
|
|
|
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 ComposeWorkflowConfig = 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
|
},
|