ugcinc 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accounts.d.ts +146 -1
- package/dist/automations/index.d.ts +174 -0
- package/dist/automations/index.js +194 -0
- package/dist/automations/nodes/account.d.ts +18 -0
- package/dist/automations/nodes/account.js +29 -0
- package/dist/automations/nodes/auto-caption.d.ts +64 -0
- package/dist/automations/nodes/auto-caption.js +46 -0
- package/dist/automations/nodes/auto-post.d.ts +81 -0
- package/dist/automations/nodes/auto-post.js +54 -0
- package/dist/automations/nodes/branch.d.ts +58 -0
- package/dist/automations/nodes/branch.js +50 -0
- package/dist/automations/nodes/collect.d.ts +16 -0
- package/dist/automations/nodes/collect.js +56 -0
- package/dist/automations/nodes/compose-workflow.d.ts +21 -0
- package/dist/automations/nodes/compose-workflow.js +42 -0
- package/dist/automations/nodes/create-dm.d.ts +96 -0
- package/dist/automations/nodes/create-dm.js +88 -0
- package/dist/automations/nodes/custom-model.d.ts +19 -0
- package/dist/automations/nodes/custom-model.js +52 -0
- package/dist/automations/nodes/deduplicate.d.ts +8 -0
- package/dist/automations/nodes/deduplicate.js +36 -0
- package/dist/automations/nodes/destructure.d.ts +25 -0
- package/dist/automations/nodes/destructure.js +65 -0
- package/dist/automations/nodes/for-each.d.ts +23 -0
- package/dist/automations/nodes/for-each.js +84 -0
- package/dist/automations/nodes/generate-image.d.ts +16 -0
- package/dist/automations/nodes/generate-image.js +45 -0
- package/dist/automations/nodes/generate-video.d.ts +16 -0
- package/dist/automations/nodes/generate-video.js +45 -0
- package/dist/automations/nodes/if.d.ts +22 -0
- package/dist/automations/nodes/if.js +44 -0
- package/dist/automations/nodes/image-composer.d.ts +33 -0
- package/dist/automations/nodes/image-composer.js +95 -0
- package/dist/automations/nodes/index.d.ts +20 -0
- package/dist/automations/nodes/index.js +93 -0
- package/dist/automations/nodes/llm.d.ts +27 -0
- package/dist/automations/nodes/llm.js +85 -0
- package/dist/automations/nodes/manual-trigger.d.ts +34 -0
- package/dist/automations/nodes/manual-trigger.js +32 -0
- package/dist/automations/nodes/media.d.ts +17 -0
- package/dist/automations/nodes/media.js +40 -0
- package/dist/automations/nodes/not.d.ts +6 -0
- package/dist/automations/nodes/not.js +35 -0
- package/dist/automations/nodes/output.d.ts +30 -0
- package/dist/automations/nodes/output.js +32 -0
- package/dist/automations/nodes/random-route.d.ts +52 -0
- package/dist/automations/nodes/random-route.js +53 -0
- package/dist/automations/nodes/random.d.ts +16 -0
- package/dist/automations/nodes/random.js +50 -0
- package/dist/automations/nodes/recurrence.d.ts +69 -0
- package/dist/automations/nodes/recurrence.js +50 -0
- package/dist/automations/nodes/save-to-media.d.ts +32 -0
- package/dist/automations/nodes/save-to-media.js +31 -0
- package/dist/automations/nodes/screenshot-animation.d.ts +7 -0
- package/dist/automations/nodes/screenshot-animation.js +36 -0
- package/dist/automations/nodes/social-audio.d.ts +8 -0
- package/dist/automations/nodes/social-audio.js +30 -0
- package/dist/automations/nodes/text.d.ts +7 -0
- package/dist/automations/nodes/text.js +41 -0
- package/dist/automations/nodes/transcript.d.ts +6 -0
- package/dist/automations/nodes/transcript.js +46 -0
- package/dist/automations/nodes/types.d.ts +178 -0
- package/dist/automations/nodes/types.js +22 -0
- package/dist/automations/nodes/video-composer.d.ts +25 -0
- package/dist/automations/nodes/video-composer.js +71 -0
- package/dist/automations/nodes/video-import.d.ts +27 -0
- package/dist/automations/nodes/video-import.js +37 -0
- package/dist/automations/types.d.ts +544 -0
- package/dist/automations/types.js +101 -0
- package/dist/automations.d.ts +5 -33
- package/dist/automations.js +6 -647
- package/dist/comments.d.ts +26 -1
- package/dist/comments.js +3 -0
- package/dist/graph-controller.d.ts +194 -0
- package/dist/graph-controller.js +623 -0
- package/dist/index.d.ts +38 -9
- package/dist/index.js +43 -23
- package/dist/internal-utils.d.ts +8 -0
- package/dist/internal-utils.js +22 -0
- package/dist/media.d.ts +135 -1
- package/dist/nodes/account.d.ts +7 -0
- package/dist/nodes/account.js +29 -0
- package/dist/nodes/auto-caption.d.ts +17 -0
- package/dist/nodes/auto-caption.js +46 -0
- package/dist/nodes/auto-post.d.ts +21 -0
- package/dist/nodes/auto-post.js +54 -0
- package/dist/nodes/branch.d.ts +12 -0
- package/dist/nodes/branch.js +50 -0
- package/dist/nodes/collect.d.ts +6 -0
- package/dist/nodes/collect.js +56 -0
- package/dist/nodes/compose-workflow.d.ts +21 -0
- package/dist/nodes/compose-workflow.js +42 -0
- package/dist/nodes/create-dm.d.ts +40 -0
- package/dist/nodes/create-dm.js +88 -0
- package/dist/nodes/custom-model.d.ts +19 -0
- package/dist/nodes/custom-model.js +52 -0
- package/dist/nodes/deduplicate.d.ts +8 -0
- package/dist/nodes/deduplicate.js +36 -0
- package/dist/nodes/destructure.d.ts +25 -0
- package/dist/nodes/destructure.js +65 -0
- package/dist/nodes/for-each.d.ts +23 -0
- package/dist/nodes/for-each.js +84 -0
- package/dist/nodes/generate-image.d.ts +16 -0
- package/dist/nodes/generate-image.js +45 -0
- package/dist/nodes/generate-video.d.ts +16 -0
- package/dist/nodes/generate-video.js +45 -0
- package/dist/nodes/if.d.ts +22 -0
- package/dist/nodes/if.js +44 -0
- package/dist/nodes/image-composer.d.ts +14 -0
- package/dist/nodes/image-composer.js +95 -0
- package/dist/nodes/index.d.ts +20 -0
- package/dist/nodes/index.js +93 -0
- package/dist/nodes/llm.d.ts +27 -0
- package/dist/nodes/llm.js +85 -0
- package/dist/nodes/manual-trigger.d.ts +16 -0
- package/dist/nodes/manual-trigger.js +32 -0
- package/dist/nodes/media.d.ts +17 -0
- package/dist/nodes/media.js +40 -0
- package/dist/nodes/not.d.ts +6 -0
- package/dist/nodes/not.js +35 -0
- package/dist/nodes/output.d.ts +9 -0
- package/dist/nodes/output.js +32 -0
- package/dist/nodes/random-route.d.ts +3 -0
- package/dist/nodes/random-route.js +50 -0
- package/dist/nodes/random.d.ts +3 -0
- package/dist/nodes/random.js +48 -0
- package/dist/nodes/recurrence.d.ts +3 -0
- package/dist/nodes/recurrence.js +45 -0
- package/dist/nodes/save-to-media.d.ts +3 -0
- package/dist/nodes/save-to-media.js +26 -0
- package/dist/nodes/screenshot-animation.d.ts +7 -0
- package/dist/nodes/screenshot-animation.js +36 -0
- package/dist/nodes/social-audio.d.ts +3 -0
- package/dist/nodes/social-audio.js +26 -0
- package/dist/nodes/text.d.ts +3 -0
- package/dist/nodes/text.js +38 -0
- package/dist/nodes/transcript.d.ts +3 -0
- package/dist/nodes/transcript.js +42 -0
- package/dist/nodes/types.d.ts +146 -0
- package/dist/nodes/types.js +22 -0
- package/dist/nodes/video-composer.d.ts +3 -0
- package/dist/nodes/video-composer.js +67 -0
- package/dist/nodes/video-import.d.ts +3 -0
- package/dist/nodes/video-import.js +35 -0
- package/dist/org.d.ts +13 -1
- package/dist/ports.js +3 -9
- package/dist/posts.d.ts +88 -1
- package/dist/render/compositions/IMessageDmComposition/types.d.ts +20 -20
- package/dist/render/types/video.d.ts +2 -2
- package/dist/stats.d.ts +128 -1
- package/dist/tasks.d.ts +20 -1
- package/dist/types.d.ts +1 -2216
- package/dist/types.js +2 -124
- package/package.json +1 -1
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Graph Controller
|
|
4
|
+
*
|
|
5
|
+
* Centralized logic for automation graph management including:
|
|
6
|
+
* - Port computation
|
|
7
|
+
* - Connection management
|
|
8
|
+
* - Type compatibility checking
|
|
9
|
+
* - Workflow validation
|
|
10
|
+
* - For-each context validation
|
|
11
|
+
*
|
|
12
|
+
* All functions work with WorkflowNodeDefinition[] (embedded connection format).
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.areTypesCompatible = areTypesCompatible;
|
|
16
|
+
exports.computePortsForNode = computePortsForNode;
|
|
17
|
+
exports.getAllNodes = getAllNodes;
|
|
18
|
+
exports.getNodeByType = getNodeByType;
|
|
19
|
+
exports.getOutputSchema = getOutputSchema;
|
|
20
|
+
exports.deriveConnections = deriveConnections;
|
|
21
|
+
exports.addConnection = addConnection;
|
|
22
|
+
exports.removeConnection = removeConnection;
|
|
23
|
+
exports.removeNodeConnections = removeNodeConnections;
|
|
24
|
+
exports.cleanupStaleConnections = cleanupStaleConnections;
|
|
25
|
+
exports.getForEachContext = getForEachContext;
|
|
26
|
+
exports.checkCrossContextViolation = checkCrossContextViolation;
|
|
27
|
+
exports.validateWorkflow = validateWorkflow;
|
|
28
|
+
exports.getErrorNodeIds = getErrorNodeIds;
|
|
29
|
+
exports.getPortErrorsForNode = getPortErrorsForNode;
|
|
30
|
+
exports.hasMissingTriggerError = hasMissingTriggerError;
|
|
31
|
+
exports.hasMissingTerminalError = hasMissingTerminalError;
|
|
32
|
+
const types_1 = require("./automations/types");
|
|
33
|
+
const nodes_1 = require("./automations/nodes");
|
|
34
|
+
// ===========================================================================
|
|
35
|
+
// Internal Helpers (not exported)
|
|
36
|
+
// ===========================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Helper to check if a port type is a union (array of BasePortTypes)
|
|
39
|
+
*/
|
|
40
|
+
function isTypeUnion(type) {
|
|
41
|
+
return Array.isArray(type);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract template variables from text (e.g., "Hello {{name}}" -> ["name"])
|
|
45
|
+
*/
|
|
46
|
+
function extractTemplateVariables(texts) {
|
|
47
|
+
const variables = new Set();
|
|
48
|
+
const regex = /\{\{(\w+)\}\}/g;
|
|
49
|
+
for (const text of texts) {
|
|
50
|
+
let match;
|
|
51
|
+
while ((match = regex.exec(text)) !== null) {
|
|
52
|
+
if (match[1])
|
|
53
|
+
variables.add(match[1]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return Array.from(variables);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Derive Connection[] array from nodes for internal processing
|
|
60
|
+
* Connections are stored in the embedded inputs map format.
|
|
61
|
+
*/
|
|
62
|
+
function deriveConnectionsInternal(nodes) {
|
|
63
|
+
const connections = [];
|
|
64
|
+
nodes.forEach(node => {
|
|
65
|
+
if (!node.inputs)
|
|
66
|
+
return;
|
|
67
|
+
Object.entries(node.inputs).forEach(([inputId, mapping]) => {
|
|
68
|
+
connections.push({
|
|
69
|
+
id: `${mapping.sourceNodeId}-${mapping.sourceOutputId}-${node.id}-${inputId}`,
|
|
70
|
+
sourceNodeId: mapping.sourceNodeId,
|
|
71
|
+
sourceOutputId: mapping.sourceOutputId,
|
|
72
|
+
targetNodeId: node.id,
|
|
73
|
+
targetInputId: inputId,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
return connections;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get all nodes that are downstream of a for-each node (inside its context).
|
|
81
|
+
*/
|
|
82
|
+
function getDownstreamNodes(forEachNodeId, nodes) {
|
|
83
|
+
const connections = deriveConnectionsInternal(nodes);
|
|
84
|
+
const downstream = new Set();
|
|
85
|
+
const queue = [];
|
|
86
|
+
// Find direct outputs from for-each
|
|
87
|
+
for (const conn of connections) {
|
|
88
|
+
if (conn.sourceNodeId === forEachNodeId) {
|
|
89
|
+
if (!downstream.has(conn.targetNodeId)) {
|
|
90
|
+
downstream.add(conn.targetNodeId);
|
|
91
|
+
queue.push(conn.targetNodeId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// BFS to find all downstream
|
|
96
|
+
while (queue.length > 0) {
|
|
97
|
+
const currentId = queue.shift();
|
|
98
|
+
for (const conn of connections) {
|
|
99
|
+
if (conn.sourceNodeId === currentId && !downstream.has(conn.targetNodeId)) {
|
|
100
|
+
downstream.add(conn.targetNodeId);
|
|
101
|
+
queue.push(conn.targetNodeId);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return downstream;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if a node would be "captured" by a for-each context after a proposed connection.
|
|
109
|
+
*
|
|
110
|
+
* A node is captured if ALL of its outputs go to nodes inside the for-each context
|
|
111
|
+
* (either downstream nodes or other captured nodes).
|
|
112
|
+
*/
|
|
113
|
+
function wouldBeCaptured(nodeId, forEachNodeId, downstreamNodes, nodes, proposedTargetNodeId) {
|
|
114
|
+
const node = nodes.find(n => n.id === nodeId);
|
|
115
|
+
if (!node)
|
|
116
|
+
return false;
|
|
117
|
+
// For-each nodes can't be captured
|
|
118
|
+
if (node.type === 'for-each')
|
|
119
|
+
return false;
|
|
120
|
+
// Already downstream = not captured (it's inside)
|
|
121
|
+
if (downstreamNodes.has(nodeId))
|
|
122
|
+
return false;
|
|
123
|
+
const connections = deriveConnectionsInternal(nodes);
|
|
124
|
+
// Get all targets this node outputs to (existing + proposed)
|
|
125
|
+
const outputTargets = new Set();
|
|
126
|
+
for (const conn of connections) {
|
|
127
|
+
if (conn.sourceNodeId === nodeId) {
|
|
128
|
+
outputTargets.add(conn.targetNodeId);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Add the proposed connection target
|
|
132
|
+
outputTargets.add(proposedTargetNodeId);
|
|
133
|
+
// If no outputs, can't be captured
|
|
134
|
+
if (outputTargets.size === 0)
|
|
135
|
+
return false;
|
|
136
|
+
// Build captured set iteratively
|
|
137
|
+
const captured = new Set();
|
|
138
|
+
let changed = true;
|
|
139
|
+
while (changed) {
|
|
140
|
+
changed = false;
|
|
141
|
+
for (const n of nodes) {
|
|
142
|
+
if (n.id === forEachNodeId)
|
|
143
|
+
continue;
|
|
144
|
+
if (downstreamNodes.has(n.id))
|
|
145
|
+
continue;
|
|
146
|
+
if (captured.has(n.id))
|
|
147
|
+
continue;
|
|
148
|
+
// Get outputs for this node
|
|
149
|
+
const nodeOutputs = new Set();
|
|
150
|
+
for (const conn of connections) {
|
|
151
|
+
if (conn.sourceNodeId === n.id) {
|
|
152
|
+
nodeOutputs.add(conn.targetNodeId);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Include proposed connection if this is the source node
|
|
156
|
+
if (n.id === nodeId) {
|
|
157
|
+
nodeOutputs.add(proposedTargetNodeId);
|
|
158
|
+
}
|
|
159
|
+
if (nodeOutputs.size === 0)
|
|
160
|
+
continue;
|
|
161
|
+
// All outputs must go to downstream or captured
|
|
162
|
+
const allInside = [...nodeOutputs].every(targetId => downstreamNodes.has(targetId) || captured.has(targetId));
|
|
163
|
+
if (allInside) {
|
|
164
|
+
captured.add(n.id);
|
|
165
|
+
changed = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return captured.has(nodeId);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Find the for-each context a node belongs to by tracing backwards.
|
|
173
|
+
*
|
|
174
|
+
* A node is "inside" a for-each context if, when tracing backwards through
|
|
175
|
+
* connections, we reach a for-each node via one of its OUTPUT ports.
|
|
176
|
+
*
|
|
177
|
+
* Returns the for-each node ID if inside a context, or null if outside all contexts.
|
|
178
|
+
*/
|
|
179
|
+
function getForEachContextInternal(nodeId, nodes, connections, visited = new Set()) {
|
|
180
|
+
// Prevent infinite loops from circular references
|
|
181
|
+
if (visited.has(nodeId))
|
|
182
|
+
return null;
|
|
183
|
+
visited.add(nodeId);
|
|
184
|
+
const node = nodes.find(n => n.id === nodeId);
|
|
185
|
+
if (!node)
|
|
186
|
+
return null;
|
|
187
|
+
// Check all inputs to this node
|
|
188
|
+
for (const connection of connections) {
|
|
189
|
+
if (connection.targetNodeId !== nodeId)
|
|
190
|
+
continue;
|
|
191
|
+
const sourceNode = nodes.find(n => n.id === connection.sourceNodeId);
|
|
192
|
+
if (!sourceNode)
|
|
193
|
+
continue;
|
|
194
|
+
// If the source is a for-each node and we're connected to one of its outputs,
|
|
195
|
+
// then this node is inside that for-each context
|
|
196
|
+
if (sourceNode.type === 'for-each') {
|
|
197
|
+
return sourceNode.id;
|
|
198
|
+
}
|
|
199
|
+
// Otherwise, recursively check the source node's context
|
|
200
|
+
const sourceContext = getForEachContextInternal(connection.sourceNodeId, nodes, connections, visited);
|
|
201
|
+
if (sourceContext) {
|
|
202
|
+
return sourceContext;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
// ===========================================================================
|
|
208
|
+
// Type Compatibility
|
|
209
|
+
// ===========================================================================
|
|
210
|
+
/**
|
|
211
|
+
* Check if two port types are compatible for connection
|
|
212
|
+
* A connection is valid if:
|
|
213
|
+
* 1. The types match exactly (same base type and same isArray), OR
|
|
214
|
+
* 2. The source is an array type and target is 'object' (non-array), OR
|
|
215
|
+
* 3. The source is a union and includes a compatible type, OR
|
|
216
|
+
* 4. The target is a union and includes a compatible type, OR
|
|
217
|
+
* 5. Both are unions and have at least one common compatible type
|
|
218
|
+
*
|
|
219
|
+
* Note: Array inputs are strict - they only accept exact matches
|
|
220
|
+
*/
|
|
221
|
+
function areTypesCompatible({ sourceType, sourceIsArray, targetType, targetIsArray, }) {
|
|
222
|
+
const sourceTypes = isTypeUnion(sourceType) ? sourceType : [sourceType];
|
|
223
|
+
const targetTypes = isTypeUnion(targetType) ? targetType : [targetType];
|
|
224
|
+
return sourceTypes.some(st => {
|
|
225
|
+
return targetTypes.some(tt => {
|
|
226
|
+
// Exact match (same base type and same isArray)
|
|
227
|
+
if (st === tt && sourceIsArray === targetIsArray)
|
|
228
|
+
return true;
|
|
229
|
+
// Object inputs (non-array) accept any array type (backwards compatibility with for-each, etc.)
|
|
230
|
+
if (tt === 'object' && !targetIsArray && sourceIsArray) {
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
// Array inputs are strict - no other compatibility
|
|
234
|
+
if (targetIsArray) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// ===========================================================================
|
|
242
|
+
// Port Computation
|
|
243
|
+
// ===========================================================================
|
|
244
|
+
/**
|
|
245
|
+
* Compute ports for a node based on its type and config.
|
|
246
|
+
* Uses the node definition's computePorts function.
|
|
247
|
+
*
|
|
248
|
+
* @param nodeType - The type of the node
|
|
249
|
+
* @param config - The node's configuration object
|
|
250
|
+
* @param getConnectedOutput - Optional function to get connected output port info (for dynamic ports)
|
|
251
|
+
*/
|
|
252
|
+
function computePortsForNode({ nodeType, config, getConnectedOutput, }) {
|
|
253
|
+
const definition = (0, nodes_1.getNodeDefinition)(nodeType);
|
|
254
|
+
if (!definition) {
|
|
255
|
+
return { inputs: [], outputs: [] };
|
|
256
|
+
}
|
|
257
|
+
return definition.computePorts({
|
|
258
|
+
config: config ?? definition.defaults,
|
|
259
|
+
getConnectedOutput,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get all available automation nodes.
|
|
264
|
+
* Converts node definitions from the registry into NodeControlConfig format.
|
|
265
|
+
*/
|
|
266
|
+
function getAllNodes() {
|
|
267
|
+
return (0, nodes_1.getAllNodeDefinitions)().map(def => {
|
|
268
|
+
const { inputs, outputs } = def.computePorts({ config: def.defaults });
|
|
269
|
+
return {
|
|
270
|
+
nodeId: def.nodeId,
|
|
271
|
+
label: def.label,
|
|
272
|
+
description: def.description,
|
|
273
|
+
category: def.category,
|
|
274
|
+
type: def.type,
|
|
275
|
+
inputs,
|
|
276
|
+
outputs,
|
|
277
|
+
outputModes: def.outputModes,
|
|
278
|
+
selectionModes: def.selectionModes,
|
|
279
|
+
defaults: def.defaults,
|
|
280
|
+
};
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get a specific node by nodeId
|
|
285
|
+
*/
|
|
286
|
+
function getNodeByType(nodeId) {
|
|
287
|
+
return getAllNodes().find(node => node.nodeId === nodeId);
|
|
288
|
+
}
|
|
289
|
+
// ===========================================================================
|
|
290
|
+
// Output Schema
|
|
291
|
+
// ===========================================================================
|
|
292
|
+
/**
|
|
293
|
+
* Get the schema of array items for a node's output port.
|
|
294
|
+
* Returns null if schema is unknown or the output is not an array.
|
|
295
|
+
*
|
|
296
|
+
* @param nodeType - The type of the node (e.g., 'transcript', 'llm')
|
|
297
|
+
* @param nodeConfig - The node's configuration object
|
|
298
|
+
* @param outputPortId - The ID of the output port to get schema for
|
|
299
|
+
* @returns The schema of array items, or null if unknown
|
|
300
|
+
*/
|
|
301
|
+
function getOutputSchema({ nodeType, nodeConfig, outputPortId, }) {
|
|
302
|
+
// First check static node definitions
|
|
303
|
+
const nodeDefinition = getNodeByType(nodeType);
|
|
304
|
+
const outputPort = nodeDefinition?.outputs.find(o => o.id === outputPortId);
|
|
305
|
+
if (outputPort?.objectSchema) {
|
|
306
|
+
return outputPort.objectSchema;
|
|
307
|
+
}
|
|
308
|
+
// Check resolvedPorts for nodes with dynamic outputs (compose-workflow, for-each, etc.)
|
|
309
|
+
if (nodeConfig?.resolvedPorts) {
|
|
310
|
+
const resolvedPorts = nodeConfig.resolvedPorts;
|
|
311
|
+
const resolvedOutput = resolvedPorts.outputs?.find(o => o.id === outputPortId);
|
|
312
|
+
if (resolvedOutput?.objectSchema) {
|
|
313
|
+
return resolvedOutput.objectSchema;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
// ===========================================================================
|
|
319
|
+
// Connection Management
|
|
320
|
+
// ===========================================================================
|
|
321
|
+
/**
|
|
322
|
+
* Derive Connection[] array from nodes for canvas rendering
|
|
323
|
+
*
|
|
324
|
+
* Connections are stored in the embedded inputs map format.
|
|
325
|
+
* This function extracts them into a flat array for canvas rendering.
|
|
326
|
+
*/
|
|
327
|
+
function deriveConnections({ nodes }) {
|
|
328
|
+
return deriveConnectionsInternal(nodes);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Add a connection to a node's inputs map
|
|
332
|
+
*/
|
|
333
|
+
function addConnection({ nodes, sourceNodeId, sourceOutputId, targetNodeId, targetInputId, }) {
|
|
334
|
+
return nodes.map(node => {
|
|
335
|
+
if (node.id !== targetNodeId)
|
|
336
|
+
return node;
|
|
337
|
+
return {
|
|
338
|
+
...node,
|
|
339
|
+
inputs: {
|
|
340
|
+
...node.inputs,
|
|
341
|
+
[targetInputId]: {
|
|
342
|
+
sourceNodeId,
|
|
343
|
+
sourceOutputId,
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Remove a connection from a node's inputs map
|
|
351
|
+
*/
|
|
352
|
+
function removeConnection({ nodes, targetNodeId, targetInputId, }) {
|
|
353
|
+
return nodes.map(node => {
|
|
354
|
+
if (node.id !== targetNodeId)
|
|
355
|
+
return node;
|
|
356
|
+
const newInputs = { ...node.inputs };
|
|
357
|
+
delete newInputs[targetInputId];
|
|
358
|
+
return {
|
|
359
|
+
...node,
|
|
360
|
+
inputs: newInputs,
|
|
361
|
+
};
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Remove all connections to/from a node
|
|
366
|
+
*/
|
|
367
|
+
function removeNodeConnections({ nodes, nodeId, }) {
|
|
368
|
+
return nodes.map(node => {
|
|
369
|
+
// Remove inputs that come from the deleted node
|
|
370
|
+
const newInputs = { ...node.inputs };
|
|
371
|
+
let hasChanges = false;
|
|
372
|
+
Object.entries(newInputs).forEach(([inputId, mapping]) => {
|
|
373
|
+
if (mapping.sourceNodeId === nodeId) {
|
|
374
|
+
delete newInputs[inputId];
|
|
375
|
+
hasChanges = true;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
if (hasChanges) {
|
|
379
|
+
return { ...node, inputs: newInputs };
|
|
380
|
+
}
|
|
381
|
+
return node;
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Clean up stale connections on load.
|
|
386
|
+
*
|
|
387
|
+
* Removes entries from node.inputs that reference ports that no longer exist
|
|
388
|
+
* in the node's resolvedPorts.inputs. This handles cases where ports were
|
|
389
|
+
* renamed or deleted but the old connection data persisted.
|
|
390
|
+
*/
|
|
391
|
+
function cleanupStaleConnections({ nodes, }) {
|
|
392
|
+
return nodes.map(node => {
|
|
393
|
+
const resolvedInputs = node.config?.resolvedPorts?.inputs;
|
|
394
|
+
// If no resolvedPorts.inputs, we can't validate - skip cleanup for this node
|
|
395
|
+
if (!resolvedInputs || !Array.isArray(resolvedInputs)) {
|
|
396
|
+
return node;
|
|
397
|
+
}
|
|
398
|
+
const validInputIds = new Set(resolvedInputs.map(p => p.id));
|
|
399
|
+
const currentInputs = node.inputs ?? {};
|
|
400
|
+
// Check if any inputs are stale (reference non-existent ports)
|
|
401
|
+
const staleInputIds = Object.keys(currentInputs).filter(inputId => !validInputIds.has(inputId));
|
|
402
|
+
if (staleInputIds.length === 0) {
|
|
403
|
+
return node; // No cleanup needed
|
|
404
|
+
}
|
|
405
|
+
// Remove stale inputs
|
|
406
|
+
const cleanedInputs = { ...currentInputs };
|
|
407
|
+
staleInputIds.forEach(inputId => {
|
|
408
|
+
delete cleanedInputs[inputId];
|
|
409
|
+
});
|
|
410
|
+
return {
|
|
411
|
+
...node,
|
|
412
|
+
inputs: cleanedInputs,
|
|
413
|
+
};
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
// ===========================================================================
|
|
417
|
+
// For-Each Context Validation
|
|
418
|
+
// ===========================================================================
|
|
419
|
+
/**
|
|
420
|
+
* Find the for-each context a node belongs to by tracing backwards.
|
|
421
|
+
*
|
|
422
|
+
* A node is "inside" a for-each context if, when tracing backwards through
|
|
423
|
+
* connections, we reach a for-each node via one of its OUTPUT ports.
|
|
424
|
+
*
|
|
425
|
+
* Returns the for-each node ID if inside a context, or null if outside all contexts.
|
|
426
|
+
*/
|
|
427
|
+
function getForEachContext({ nodeId, nodes, }) {
|
|
428
|
+
const connections = deriveConnectionsInternal(nodes);
|
|
429
|
+
return getForEachContextInternal(nodeId, nodes, connections);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Check if a connection would violate for-each context boundaries.
|
|
433
|
+
*
|
|
434
|
+
* A violation occurs when:
|
|
435
|
+
* 1. Source is OUTSIDE a for-each context and target is INSIDE,
|
|
436
|
+
* AND the source would NOT become a "captured" node after this connection
|
|
437
|
+
* 2. Source and target are in DIFFERENT for-each contexts
|
|
438
|
+
* (can't connect across different loops)
|
|
439
|
+
*
|
|
440
|
+
* "Captured" nodes are allowed - they will be expanded at runtime to execute
|
|
441
|
+
* once per for-each iteration (e.g., Account selector → Auto Post inside for-each).
|
|
442
|
+
*
|
|
443
|
+
* Returns true if the connection is INVALID (violation), false if allowed.
|
|
444
|
+
*/
|
|
445
|
+
function checkCrossContextViolation({ sourceNodeId, targetNodeId, nodes, }) {
|
|
446
|
+
const connections = deriveConnectionsInternal(nodes);
|
|
447
|
+
const targetNode = nodes.find(n => n.id === targetNodeId);
|
|
448
|
+
if (!targetNode)
|
|
449
|
+
return false;
|
|
450
|
+
// If target is a for-each node, the connection is going INTO the for-each
|
|
451
|
+
// (to its array input or passthrough inputs), which is always allowed
|
|
452
|
+
if (targetNode.type === 'for-each') {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
const sourceNode = nodes.find(n => n.id === sourceNodeId);
|
|
456
|
+
const targetContext = getForEachContextInternal(targetNodeId, nodes, connections);
|
|
457
|
+
// If source IS the for-each node that defines the target's context,
|
|
458
|
+
// allow the connection (for-each feeding its own loop body via passthrough outputs)
|
|
459
|
+
if (sourceNode?.type === 'for-each' && targetContext === sourceNodeId) {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
const sourceContext = getForEachContextInternal(sourceNodeId, nodes, connections);
|
|
463
|
+
// If source is outside and target is inside a for-each context...
|
|
464
|
+
if (sourceContext === null && targetContext !== null) {
|
|
465
|
+
// Check if source would become a "captured" node after this connection
|
|
466
|
+
const downstreamNodes = getDownstreamNodes(targetContext, nodes);
|
|
467
|
+
if (wouldBeCaptured(sourceNodeId, targetContext, downstreamNodes, nodes, targetNodeId)) {
|
|
468
|
+
// Source will be captured - allow the connection
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
// Source has other outputs outside the context - violation
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
// If both are inside different for-each contexts, that's a violation
|
|
475
|
+
if (sourceContext !== null && targetContext !== null && sourceContext !== targetContext) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
// ===========================================================================
|
|
481
|
+
// Workflow Validation
|
|
482
|
+
// ===========================================================================
|
|
483
|
+
const TRIGGER_TYPES = ['manual-trigger', 'recurrence'];
|
|
484
|
+
const TERMINAL_TYPES = ['passthrough', 'auto-post', 'save-to-media'];
|
|
485
|
+
/**
|
|
486
|
+
* Validate workflow and return structured errors for UI highlighting
|
|
487
|
+
*/
|
|
488
|
+
function validateWorkflow({ nodes, }) {
|
|
489
|
+
const errors = [];
|
|
490
|
+
const connections = deriveConnectionsInternal(nodes);
|
|
491
|
+
// 1. Check for trigger node
|
|
492
|
+
const hasTrigger = nodes.some(n => TRIGGER_TYPES.includes(n.type));
|
|
493
|
+
if (!hasTrigger) {
|
|
494
|
+
errors.push({
|
|
495
|
+
type: 'missing_trigger',
|
|
496
|
+
message: 'Automation requires a trigger node (Manual Trigger or Recurrence)',
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
// 2. Check for terminal node
|
|
500
|
+
const hasTerminal = nodes.some(n => TERMINAL_TYPES.includes(n.type));
|
|
501
|
+
if (!hasTerminal) {
|
|
502
|
+
errors.push({
|
|
503
|
+
type: 'missing_terminal',
|
|
504
|
+
message: 'Automation requires an output node (Output, Auto Post, or Save to Media)',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
// Build connection lookup: targetNodeId-targetInputId -> connection
|
|
508
|
+
const connectionsByTarget = new Map();
|
|
509
|
+
connections.forEach(conn => {
|
|
510
|
+
connectionsByTarget.set(`${conn.targetNodeId}-${conn.targetInputId}`, conn);
|
|
511
|
+
});
|
|
512
|
+
// Build node lookup by ID
|
|
513
|
+
const nodeById = new Map();
|
|
514
|
+
nodes.forEach(n => nodeById.set(n.id, n));
|
|
515
|
+
// 3. Check each node for missing required inputs and type mismatches
|
|
516
|
+
for (const node of nodes) {
|
|
517
|
+
// Use node definition's computePorts if available
|
|
518
|
+
const definition = (0, nodes_1.getNodeDefinition)(node.type);
|
|
519
|
+
const inputPorts = definition
|
|
520
|
+
? definition.computePorts({ config: node.config ?? {} }).inputs
|
|
521
|
+
: [];
|
|
522
|
+
for (const port of inputPorts) {
|
|
523
|
+
if (!port.required)
|
|
524
|
+
continue;
|
|
525
|
+
const connectionKey = `${node.id}-${port.id}`;
|
|
526
|
+
const connection = connectionsByTarget.get(connectionKey);
|
|
527
|
+
if (!connection) {
|
|
528
|
+
// Missing required input
|
|
529
|
+
errors.push({
|
|
530
|
+
type: 'missing_required_input',
|
|
531
|
+
nodeId: node.id,
|
|
532
|
+
portId: port.id,
|
|
533
|
+
message: `Required input '${port.id}' is not connected`,
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// Check type compatibility
|
|
538
|
+
const sourceNode = nodeById.get(connection.sourceNodeId);
|
|
539
|
+
if (sourceNode) {
|
|
540
|
+
const sourceDefinition = (0, nodes_1.getNodeDefinition)(sourceNode.type);
|
|
541
|
+
const sourceOutputs = sourceDefinition
|
|
542
|
+
? sourceDefinition.computePorts({ config: sourceNode.config ?? {} }).outputs
|
|
543
|
+
: [];
|
|
544
|
+
const sourcePort = sourceOutputs.find(p => p.id === connection.sourceOutputId);
|
|
545
|
+
if (sourcePort) {
|
|
546
|
+
const compatible = areTypesCompatible({
|
|
547
|
+
sourceType: sourcePort.type,
|
|
548
|
+
sourceIsArray: sourcePort.isArray,
|
|
549
|
+
targetType: port.type,
|
|
550
|
+
targetIsArray: port.isArray,
|
|
551
|
+
});
|
|
552
|
+
if (!compatible) {
|
|
553
|
+
errors.push({
|
|
554
|
+
type: 'type_mismatch',
|
|
555
|
+
nodeId: node.id,
|
|
556
|
+
portId: port.id,
|
|
557
|
+
message: `Type mismatch: expected ${formatPortType(port.type, port.isArray)}, got ${formatPortType(sourcePort.type, sourcePort.isArray)}`,
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
// 4. Check for empty media pool
|
|
565
|
+
if (node.type === 'media') {
|
|
566
|
+
const configOutputs = (node.config?.outputs ?? []);
|
|
567
|
+
// Check if ANY output has media selected
|
|
568
|
+
const totalSelected = configOutputs.reduce((sum, o) => sum + o.selectedMediaIds.length, 0);
|
|
569
|
+
if (totalSelected === 0) {
|
|
570
|
+
errors.push({
|
|
571
|
+
type: 'empty_media_pool',
|
|
572
|
+
nodeId: node.id,
|
|
573
|
+
message: 'Media node has no media selected',
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
// 5. Check for empty account pool
|
|
578
|
+
if (node.type === 'account') {
|
|
579
|
+
const accountConfig = node.config?.accountConfig;
|
|
580
|
+
const accountIds = accountConfig?.accountIds ?? [];
|
|
581
|
+
if (accountIds.length === 0) {
|
|
582
|
+
errors.push({
|
|
583
|
+
type: 'empty_account_pool',
|
|
584
|
+
nodeId: node.id,
|
|
585
|
+
message: 'Account node has no accounts selected',
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return errors;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Format a port type for display in error messages
|
|
594
|
+
*/
|
|
595
|
+
function formatPortType(type, isArray) {
|
|
596
|
+
return (0, types_1.formatPortType)(type, isArray);
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Get node IDs that have errors
|
|
600
|
+
*/
|
|
601
|
+
function getErrorNodeIds({ errors }) {
|
|
602
|
+
return [...new Set(errors.filter(e => e.nodeId).map(e => e.nodeId))];
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Get port errors for a specific node
|
|
606
|
+
*/
|
|
607
|
+
function getPortErrorsForNode({ nodeId, errors, }) {
|
|
608
|
+
return errors
|
|
609
|
+
.filter(e => e.nodeId === nodeId && e.portId)
|
|
610
|
+
.map(e => ({ portId: e.portId, message: e.message }));
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Check if there's a missing trigger error
|
|
614
|
+
*/
|
|
615
|
+
function hasMissingTriggerError({ errors }) {
|
|
616
|
+
return errors.some(e => e.type === 'missing_trigger');
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Check if there's a missing terminal error
|
|
620
|
+
*/
|
|
621
|
+
function hasMissingTerminalError({ errors }) {
|
|
622
|
+
return errors.some(e => e.type === 'missing_terminal');
|
|
623
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,15 +10,44 @@ export { PostsClient } from './posts';
|
|
|
10
10
|
export { StatsClient } from './stats';
|
|
11
11
|
export { OrganizationClient } from './org';
|
|
12
12
|
export { RenderClient } from './render';
|
|
13
|
-
export { AutomationsClient
|
|
14
|
-
export { computeInputPorts, computeOutputPorts, isInputPortRequired, extractTemplateVariables } from './ports';
|
|
15
|
-
export type { ComputedPort } from './ports';
|
|
16
|
-
export { NodeTypes, isAsyncExecutor, isEditModel, isImageToVideoModel, portType, formatPortType, isLegacyPortType, fromLegacyPortType, toLegacyPortType, normalizePortType, normalizePortTypes } from './types';
|
|
17
|
-
export type { PropertySchema } from './automations';
|
|
18
|
-
export { portId, isValidPortId, portIdToTitle, normalizeToPortId, PortIdSchema } from './port-id';
|
|
19
|
-
export type { PortId } from './port-id';
|
|
13
|
+
export { AutomationsClient } from './automations';
|
|
20
14
|
export { MediaClient } from './media';
|
|
21
15
|
export { CommentsClient } from './comments';
|
|
16
|
+
export { areTypesCompatible, computePortsForNode, getAllNodes, getNodeByType, getOutputSchema, deriveConnections, addConnection, removeConnection, removeNodeConnections, cleanupStaleConnections, getForEachContext, checkCrossContextViolation, validateWorkflow, getErrorNodeIds, getPortErrorsForNode, hasMissingTriggerError, hasMissingTerminalError, } from './graph-controller';
|
|
17
|
+
export { NodeTypes, isAsyncExecutor, formatPortType } from './automations/types';
|
|
18
|
+
export { isEditModel } from './automations/nodes/generate-image';
|
|
19
|
+
export { isImageToVideoModel } from './automations/nodes/generate-video';
|
|
20
|
+
export { portId, isValidPortId, portIdToTitle, normalizeToPortId, PortIdSchema } from './port-id';
|
|
21
|
+
export type { PortId } from './port-id';
|
|
22
|
+
export type { ClientConfig } from './base';
|
|
23
|
+
export type { Account, AccountStat, AccountTask, EditProfileInfo, GetAccountsParams, GetAccountStatsParams, GetAccountStatusParams, AccountInfoUpdate, UpdateAccountInfoParams, AccountInfoUpdateResult, UpdateAccountInfoResponse, AccountSocialUpdate, UpdateAccountSocialParams, AccountSocialUpdateResult, UpdateAccountSocialResponse, DeleteAccountPostsParams, DeleteAccountPostsResponse, ResetWarmupParams, ResetWarmupResponse, } from './accounts';
|
|
24
|
+
export type { TaskType, Task, GetTasksParams } from './tasks';
|
|
25
|
+
export type { PostType, PostStatus, Post, PostStat, GetPostsParams, CreateSlideshowParams, GetPostStatsParams, GetPostStatusParams, CreateVideoParams, DeletePostsParams, DeletePostsResponse, RetryPostsParams, SetPostStatusParams, SetPostStatusResponse, } from './posts';
|
|
26
|
+
export type { RefreshStatsParams, RefreshStatsError, RefreshStatsResponse, DailyAggregatedStat, GetDailyAggregatedStatsParams, DailyAccountStat, GetDailyAccountStatsParams, DailyPostStat, GetDailyPostStatsParams, TopAccount, GetTopAccountsParams, TopPost, GetTopPostsParams, } from './stats';
|
|
27
|
+
export type { ApiKey, DeleteApiKeyParams, EditApiKeyParams } from './org';
|
|
28
|
+
export type { UserMedia, MediaUse, SocialAudio, Media, GetMediaParams, GetSocialAudioParams, UploadMediaParams, UploadMediaResponse, MediaTagUpdate, UpdateMediaTagsParams, MediaTagUpdateResult, UpdateMediaTagsResponse, UpdateMediaTagParams, DeleteMediaParams, DeleteMediaResponse, CreateSocialAudioParams, ImportTextParams, ImportTextResponse, CreateMediaFromUrlParams, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, GetUploadTokenParams, UploadTokenResponse, } from './media';
|
|
29
|
+
export type { CommentStatus, Comment, CreateCommentParams, CreateCommentResponse, GetCommentsParams, } from './comments';
|
|
22
30
|
export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
|
|
23
|
-
export type {
|
|
24
|
-
export type {
|
|
31
|
+
export type { VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, VideoEditorImageSequenceSegment, VideoEditorVideoSequenceSegment, TimeValue, TimeMode, SegmentTimelinePosition, DeduplicationInput, ImageEditorElement, ImageEditorNodeConfig, DimensionPresetKey, } from './render/types';
|
|
32
|
+
export type { MediaType, BasePortType, EnumOption, SelectionMode, ExhaustionBehavior, SelectionConfig, SelectionState, OutputMode, NodeOutputValues, NodePort, ResolvedPort, ResolvedPorts, NodeCategory, NodeControlConfig, NodeDefinition, NodeTypeEnum, NodeType, UserCreatableNodeType, OutputSchemaProperty, WorkflowNodeDefinition, CanvasState, WorkflowDefinition, TemplateNode, AutomationTemplate, AutomationRun, ExecutorNode, ExecutionEdge, AccountData, FlowControlOutput, ExecutorContext, NodeExecutor, AsyncNodeExecutor, ExecutorAsyncJobStatus, ValidationErrorType, ValidationError, ExportedNode, ExportedConnection, ExportedTemplate, AutomationExport, ExportedExecutor, ExportedEdge, ExportedRun, AutomationRunExport, } from './automations/types';
|
|
33
|
+
export type { MediaNodeOutput, MediaNodeEnabledType, MediaConfig } from './automations/nodes/media';
|
|
34
|
+
export type { ScreenshotAnimationConfig } from './automations/nodes/screenshot-animation';
|
|
35
|
+
/** @deprecated Use ScreenshotAnimationConfig instead */
|
|
36
|
+
export type { ScreenshotAnimationConfig as ScreenshotAnimationNodeConfig } from './automations/nodes/screenshot-animation';
|
|
37
|
+
export type { RandomRouteBranch, RandomRouteObjectField, RandomRoutePassthroughInput, RandomRouteNodeConfig, } from './automations/nodes/random-route';
|
|
38
|
+
export type { BranchDefinition, BranchValueConfig, BranchPassthroughInput, BranchNodeConfig, } from './automations/nodes/branch';
|
|
39
|
+
export type { VideoImportPlatform, VideoImportQuality, VideoImportNodeConfig, } from './automations/nodes/video-import';
|
|
40
|
+
export type { AutoCaptionPreset, AutoCaptionFontWeight, AutoCaptionPosition, AutoCaptionNodeConfig, } from './automations/nodes/auto-caption';
|
|
41
|
+
export type { CreateDmMessage, CreateDmNodeConfig, } from './automations/nodes/create-dm';
|
|
42
|
+
export type { CollectNodeConfig } from './automations/nodes/collect';
|
|
43
|
+
export type { OutputInput, OutputNodeConfig, } from './automations/nodes/output';
|
|
44
|
+
export type { ManualTriggerOutput, ManualTriggerNodeConfig, } from './automations/nodes/manual-trigger';
|
|
45
|
+
export type { DayOfWeek, RecurrenceMediaOutput, RecurrenceMediaConfig, RecurrenceNodeConfig, RecurrenceMediaEnabledType, } from './automations/nodes/recurrence';
|
|
46
|
+
export type { AccountNodeConfig } from './automations/nodes/account';
|
|
47
|
+
export type { PostSchedulingMode, PostSchedulingConfig, AutoPostMode, AutoPostInputType, AutoPostInput, AutoPostNodeConfig, } from './automations/nodes/auto-post';
|
|
48
|
+
export type { SaveToMediaInput, SaveToMediaNodeConfig, } from './automations/nodes/save-to-media';
|
|
49
|
+
export type { TriggerIterationMode, IterationExhaustionBehavior, CollectionSelectionMode, TriggerCollectionConfig, ObjectSchemaField, } from './automations/nodes/types';
|
|
50
|
+
export type { ImageComposerConfig, ImageEditorNodeInput, ImageEditorNodeOutput, } from './automations/nodes/image-composer';
|
|
51
|
+
export type { VideoComposerConfig, VideoEditorNodeInput, } from './automations/nodes/video-composer';
|
|
52
|
+
export type { SuccessResponse, ErrorResponse, ApiResponse, } from './types';
|
|
53
|
+
export type { CropBoundary, CropAxisConfig, DynamicCropConfig, BorderRadiusConfig, VerticalAnchor, HorizontalAnchor, HorizontalSelfAnchor, VerticalSelfAnchor, RelativePositionConfigX, RelativePositionConfigY, } from './render/types';
|