ugcinc 4.0.2 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +6 -0
- package/dist/automations/nodes/account.js +28 -0
- package/dist/automations/nodes/auto-caption.d.ts +23 -0
- package/dist/automations/nodes/auto-caption.js +49 -0
- package/dist/automations/nodes/auto-post.d.ts +22 -0
- package/dist/automations/nodes/auto-post.js +52 -0
- package/dist/automations/nodes/branch.d.ts +21 -0
- package/dist/automations/nodes/branch.js +46 -0
- package/dist/automations/nodes/collect.d.ts +7 -0
- package/dist/automations/nodes/collect.js +51 -0
- package/dist/automations/nodes/compose-workflow.d.ts +8 -0
- package/dist/automations/nodes/compose-workflow.js +61 -0
- package/dist/automations/nodes/create-dm.d.ts +35 -0
- package/dist/automations/nodes/create-dm.js +86 -0
- package/dist/automations/nodes/custom-model.d.ts +18 -0
- package/dist/automations/nodes/custom-model.js +52 -0
- package/dist/automations/nodes/deduplicate.d.ts +7 -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 +22 -0
- package/dist/automations/nodes/for-each.js +84 -0
- package/dist/automations/nodes/generate-image.d.ts +15 -0
- package/dist/automations/nodes/generate-image.js +45 -0
- package/dist/automations/nodes/generate-video.d.ts +15 -0
- package/dist/automations/nodes/generate-video.js +45 -0
- package/dist/automations/nodes/if.d.ts +21 -0
- package/dist/automations/nodes/if.js +44 -0
- package/dist/automations/nodes/image-composer.d.ts +46 -0
- package/dist/automations/nodes/image-composer.js +135 -0
- package/dist/automations/nodes/index.d.ts +312 -0
- package/dist/automations/nodes/index.js +92 -0
- package/dist/automations/nodes/internal.d.ts +8 -0
- package/dist/automations/nodes/internal.js +10 -0
- package/dist/automations/nodes/llm.d.ts +26 -0
- package/dist/automations/nodes/llm.js +85 -0
- package/dist/automations/nodes/manual-trigger.d.ts +14 -0
- package/dist/automations/nodes/manual-trigger.js +32 -0
- package/dist/automations/nodes/media.d.ts +13 -0
- package/dist/automations/nodes/media.js +40 -0
- package/dist/automations/nodes/not.d.ts +5 -0
- package/dist/automations/nodes/not.js +35 -0
- package/dist/automations/nodes/output.d.ts +16 -0
- package/dist/automations/nodes/output.js +32 -0
- package/dist/automations/nodes/random-route.d.ts +24 -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 +29 -0
- package/dist/automations/nodes/recurrence.js +50 -0
- package/dist/automations/nodes/save-to-media.d.ts +15 -0
- package/dist/automations/nodes/save-to-media.js +31 -0
- package/dist/automations/nodes/screenshot-animation.d.ts +6 -0
- package/dist/automations/nodes/screenshot-animation.js +36 -0
- package/dist/automations/nodes/social-audio.d.ts +7 -0
- package/dist/automations/nodes/social-audio.js +30 -0
- package/dist/automations/nodes/text.d.ts +6 -0
- package/dist/automations/nodes/text.js +41 -0
- package/dist/automations/nodes/transcript.d.ts +5 -0
- package/dist/automations/nodes/transcript.js +46 -0
- package/dist/automations/nodes/types.d.ts +202 -0
- package/dist/automations/nodes/types.js +22 -0
- package/dist/automations/nodes/video-composer.d.ts +16 -0
- package/dist/automations/nodes/video-composer.js +117 -0
- package/dist/automations/nodes/video-import.d.ts +9 -0
- package/dist/automations/nodes/video-import.js +23 -0
- package/dist/automations/types.d.ts +431 -0
- package/dist/automations/types.js +29 -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 +211 -0
- package/dist/graph-controller.js +656 -0
- package/dist/index.d.ts +22 -9
- package/dist/index.js +47 -24
- 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 +24 -24
- 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/types/video.d.ts +2 -2
- package/dist/render.d.ts +2 -1
- 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,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const types_1 = require("./types");
|
|
4
|
+
const definition = (0, types_1.defineNode)({
|
|
5
|
+
nodeId: 'for-each',
|
|
6
|
+
label: 'For Each',
|
|
7
|
+
description: 'Iterate over an array, executing downstream nodes for each item',
|
|
8
|
+
type: 'generator',
|
|
9
|
+
category: 'Control Flow',
|
|
10
|
+
outputModes: ['per-input', 'single'],
|
|
11
|
+
selectionModes: null,
|
|
12
|
+
defaults: {
|
|
13
|
+
outputProperties: [],
|
|
14
|
+
inputPorts: [],
|
|
15
|
+
exposeItem: false,
|
|
16
|
+
exposeIndex: false,
|
|
17
|
+
outputMode: 'per-input',
|
|
18
|
+
selectionMode: null,
|
|
19
|
+
},
|
|
20
|
+
computePorts: ({ config, getConnectedOutput }) => {
|
|
21
|
+
const outputProperties = config?.outputProperties ?? [];
|
|
22
|
+
const inputPorts = config?.inputPorts ?? [];
|
|
23
|
+
const exposeItem = config?.exposeItem ?? false;
|
|
24
|
+
const exposeIndex = config?.exposeIndex ?? false;
|
|
25
|
+
// Inputs: array + passthrough inputs
|
|
26
|
+
const inputs = [
|
|
27
|
+
{ id: 'array', type: 'object', isArray: false, required: true },
|
|
28
|
+
];
|
|
29
|
+
for (const port of inputPorts) {
|
|
30
|
+
inputs.push({
|
|
31
|
+
id: port.id,
|
|
32
|
+
type: port.type,
|
|
33
|
+
isArray: port.isArray,
|
|
34
|
+
required: false,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Outputs
|
|
38
|
+
const outputs = [];
|
|
39
|
+
// Determine item type from connected array input
|
|
40
|
+
let itemType = 'object';
|
|
41
|
+
if (getConnectedOutput) {
|
|
42
|
+
const connectedOutput = getConnectedOutput('array');
|
|
43
|
+
if (connectedOutput?.objectSchema) {
|
|
44
|
+
// Has objectSchema - it's an object array, use object type
|
|
45
|
+
itemType = 'object';
|
|
46
|
+
}
|
|
47
|
+
else if (connectedOutput?.type && connectedOutput.isArray) {
|
|
48
|
+
// Connected to an array type - extract the base type
|
|
49
|
+
const connType = connectedOutput.type;
|
|
50
|
+
if (!Array.isArray(connType)) {
|
|
51
|
+
itemType = connType;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Add item output if exposed
|
|
56
|
+
if (exposeItem) {
|
|
57
|
+
outputs.push({ id: 'item', type: itemType, isArray: false, required: true });
|
|
58
|
+
}
|
|
59
|
+
// Add index output if exposed
|
|
60
|
+
if (exposeIndex) {
|
|
61
|
+
outputs.push({ id: 'index', type: 'number', isArray: false, required: true });
|
|
62
|
+
}
|
|
63
|
+
// Add configured property outputs
|
|
64
|
+
for (const prop of outputProperties) {
|
|
65
|
+
outputs.push({
|
|
66
|
+
id: prop.portId,
|
|
67
|
+
type: prop.type,
|
|
68
|
+
isArray: prop.isArray,
|
|
69
|
+
required: true,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Add passthrough outputs (same value for all iterations)
|
|
73
|
+
for (const port of inputPorts) {
|
|
74
|
+
outputs.push({
|
|
75
|
+
id: port.id,
|
|
76
|
+
type: port.type,
|
|
77
|
+
isArray: port.isArray,
|
|
78
|
+
required: true,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return { inputs, outputs };
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
exports.default = definition;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type ImageGenerationTextModel = 'fal-ai/gemini-3-pro-image-preview' | 'fal-ai/nano-banana-pro' | 'fal-ai/nano-banana' | 'fal-ai/gpt-image-1/text-to-image';
|
|
2
|
+
type ImageGenerationEditModel = 'fal-ai/gemini-3-pro-image-preview/edit' | 'fal-ai/nano-banana-pro/edit' | 'fal-ai/nano-banana/edit' | 'fal-ai/gpt-image-1/edit-image';
|
|
3
|
+
type ImageGenerationModel = ImageGenerationTextModel | ImageGenerationEditModel;
|
|
4
|
+
declare function isEditModel(model: ImageGenerationModel): model is ImageGenerationEditModel;
|
|
5
|
+
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
6
|
+
model: ImageGenerationModel;
|
|
7
|
+
aspectRatio: string;
|
|
8
|
+
numImages: number;
|
|
9
|
+
apiKey: string | undefined;
|
|
10
|
+
outputMode: "per-input";
|
|
11
|
+
selectionMode: null;
|
|
12
|
+
}, false>;
|
|
13
|
+
export default definition;
|
|
14
|
+
export { isEditModel };
|
|
15
|
+
export type { ImageGenerationTextModel, ImageGenerationEditModel, ImageGenerationModel };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isEditModel = isEditModel;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
function isEditModel(model) {
|
|
6
|
+
return model.includes('/edit') || model.includes('/edit-image');
|
|
7
|
+
}
|
|
8
|
+
const definition = (0, types_1.defineNode)({
|
|
9
|
+
nodeId: 'generate-image',
|
|
10
|
+
label: 'Generate Image',
|
|
11
|
+
description: 'Generate images with AI',
|
|
12
|
+
type: 'generator',
|
|
13
|
+
category: 'AI Generation',
|
|
14
|
+
outputModes: ['per-input', 'single'],
|
|
15
|
+
selectionModes: null,
|
|
16
|
+
defaults: {
|
|
17
|
+
model: 'fal-ai/nano-banana',
|
|
18
|
+
aspectRatio: '1:1',
|
|
19
|
+
numImages: 1,
|
|
20
|
+
apiKey: undefined,
|
|
21
|
+
outputMode: 'per-input',
|
|
22
|
+
selectionMode: null,
|
|
23
|
+
},
|
|
24
|
+
computePorts: ({ config }) => {
|
|
25
|
+
const model = (config?.model ?? 'fal-ai/nano-banana');
|
|
26
|
+
const inputs = [
|
|
27
|
+
{ id: 'prompt', type: 'text', isArray: false, required: true },
|
|
28
|
+
];
|
|
29
|
+
if (isEditModel(model)) {
|
|
30
|
+
inputs.push({ id: 'image', type: 'image', isArray: false, required: true });
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
inputs,
|
|
34
|
+
outputs: [
|
|
35
|
+
{
|
|
36
|
+
id: 'output',
|
|
37
|
+
type: 'image',
|
|
38
|
+
isArray: false,
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
exports.default = definition;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type VideoGenerationTextToVideoModel = 'fal-ai/veo3.1' | 'fal-ai/veo3' | 'fal-ai/veo3/fast' | 'fal-ai/kling-video/v2.6/pro/text-to-video' | 'fal-ai/kling-video/v2.5/pro/text-to-video' | 'fal-ai/luma-dream-machine/ray-2' | 'fal-ai/luma-dream-machine/ray-2-flash' | 'fal-ai/minimax/hailuo-2.3/pro/text-to-video' | 'wan/v2.6/text-to-video' | 'fal-ai/sora-2/text-to-video';
|
|
2
|
+
type VideoGenerationImageToVideoModel = 'fal-ai/veo3.1/image-to-video' | 'fal-ai/veo3/image-to-video' | 'fal-ai/kling-video/v2.6/pro/image-to-video' | 'fal-ai/kling-video/v2.5/pro/image-to-video' | 'fal-ai/luma-dream-machine/ray-2/image-to-video' | 'fal-ai/luma-dream-machine/ray-2-flash/image-to-video' | 'fal-ai/minimax/hailuo-2.3/pro/image-to-video' | 'wan/v2.6/image-to-video' | 'fal-ai/sora-2/image-to-video/pro';
|
|
3
|
+
type VideoGenerationModel = VideoGenerationTextToVideoModel | VideoGenerationImageToVideoModel;
|
|
4
|
+
declare function isImageToVideoModel(model: VideoGenerationModel): model is VideoGenerationImageToVideoModel;
|
|
5
|
+
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
6
|
+
model: VideoGenerationModel;
|
|
7
|
+
aspectRatio: string;
|
|
8
|
+
duration: number;
|
|
9
|
+
apiKey: string | undefined;
|
|
10
|
+
outputMode: "per-input";
|
|
11
|
+
selectionMode: null;
|
|
12
|
+
}, false>;
|
|
13
|
+
export default definition;
|
|
14
|
+
export { isImageToVideoModel };
|
|
15
|
+
export type { VideoGenerationTextToVideoModel, VideoGenerationImageToVideoModel, VideoGenerationModel };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isImageToVideoModel = isImageToVideoModel;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
function isImageToVideoModel(model) {
|
|
6
|
+
return model.includes('/image-to-video');
|
|
7
|
+
}
|
|
8
|
+
const definition = (0, types_1.defineNode)({
|
|
9
|
+
nodeId: 'generate-video',
|
|
10
|
+
label: 'Generate Video',
|
|
11
|
+
description: 'Generate videos with AI',
|
|
12
|
+
type: 'generator',
|
|
13
|
+
category: 'AI Generation',
|
|
14
|
+
outputModes: ['per-input', 'single'],
|
|
15
|
+
selectionModes: null,
|
|
16
|
+
defaults: {
|
|
17
|
+
model: 'fal-ai/kling-video/v2.6/pro/text-to-video',
|
|
18
|
+
aspectRatio: '16:9',
|
|
19
|
+
duration: 5,
|
|
20
|
+
apiKey: undefined,
|
|
21
|
+
outputMode: 'per-input',
|
|
22
|
+
selectionMode: null,
|
|
23
|
+
},
|
|
24
|
+
computePorts: ({ config }) => {
|
|
25
|
+
const model = (config?.model ?? 'fal-ai/kling-video/v2.6/pro/text-to-video');
|
|
26
|
+
const inputs = [
|
|
27
|
+
{ id: 'prompt', type: 'text', isArray: false, required: true },
|
|
28
|
+
];
|
|
29
|
+
if (isImageToVideoModel(model)) {
|
|
30
|
+
inputs.push({ id: 'image', type: 'image', isArray: false, required: true });
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
inputs,
|
|
34
|
+
outputs: [
|
|
35
|
+
{
|
|
36
|
+
id: 'output',
|
|
37
|
+
type: 'video',
|
|
38
|
+
isArray: false,
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
exports.default = definition;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BasePortType } from '../types';
|
|
2
|
+
declare const IfLogicOperators: readonly ["and", "or", "xor", "nor"];
|
|
3
|
+
type IfLogicOperator = typeof IfLogicOperators[number];
|
|
4
|
+
interface IfBooleanInput {
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
interface IfPassthroughInput {
|
|
8
|
+
id: string;
|
|
9
|
+
type: BasePortType;
|
|
10
|
+
isArray: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
13
|
+
logicOperator: IfLogicOperator;
|
|
14
|
+
booleanInputs: IfBooleanInput[];
|
|
15
|
+
passthroughInputs: IfPassthroughInput[];
|
|
16
|
+
outputMode: "per-input";
|
|
17
|
+
selectionMode: null;
|
|
18
|
+
}, false>;
|
|
19
|
+
export default definition;
|
|
20
|
+
export { IfLogicOperators };
|
|
21
|
+
export type { IfLogicOperator, IfBooleanInput, IfPassthroughInput };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IfLogicOperators = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const IfLogicOperators = ['and', 'or', 'xor', 'nor'];
|
|
6
|
+
exports.IfLogicOperators = IfLogicOperators;
|
|
7
|
+
const definition = (0, types_1.defineNode)({
|
|
8
|
+
nodeId: 'if',
|
|
9
|
+
label: 'If',
|
|
10
|
+
description: 'Conditional branching based on boolean logic',
|
|
11
|
+
type: 'generator',
|
|
12
|
+
category: 'Control Flow',
|
|
13
|
+
outputModes: ['per-input', 'single'],
|
|
14
|
+
selectionModes: null,
|
|
15
|
+
defaults: {
|
|
16
|
+
logicOperator: 'and',
|
|
17
|
+
booleanInputs: [{ id: 'condition-1' }],
|
|
18
|
+
passthroughInputs: [{
|
|
19
|
+
id: 'value',
|
|
20
|
+
type: 'image',
|
|
21
|
+
isArray: false,
|
|
22
|
+
}],
|
|
23
|
+
outputMode: 'per-input',
|
|
24
|
+
selectionMode: null,
|
|
25
|
+
},
|
|
26
|
+
computePorts: ({ config }) => {
|
|
27
|
+
const booleanInputs = config?.booleanInputs ?? [];
|
|
28
|
+
const passthroughInputs = config?.passthroughInputs ?? [];
|
|
29
|
+
const inputs = [];
|
|
30
|
+
const outputs = [];
|
|
31
|
+
// Boolean condition inputs
|
|
32
|
+
for (const boolInput of booleanInputs) {
|
|
33
|
+
inputs.push({ id: boolInput.id, type: 'boolean', isArray: false, required: true });
|
|
34
|
+
}
|
|
35
|
+
// Passthrough inputs and true/false outputs
|
|
36
|
+
for (const passthrough of passthroughInputs) {
|
|
37
|
+
inputs.push({ id: passthrough.id, type: passthrough.type, isArray: passthrough.isArray, required: true });
|
|
38
|
+
outputs.push({ id: `true-${passthrough.id}`, type: passthrough.type, isArray: passthrough.isArray, required: true });
|
|
39
|
+
outputs.push({ id: `false-${passthrough.id}`, type: passthrough.type, isArray: passthrough.isArray, required: true });
|
|
40
|
+
}
|
|
41
|
+
return { inputs, outputs };
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
exports.default = definition;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ImageEditorElement, DimensionPresetKey, FitMode, DynamicCropConfig } from '../../render/types';
|
|
2
|
+
/**
|
|
3
|
+
* Image editor node configuration
|
|
4
|
+
*
|
|
5
|
+
* This is the complete configuration for an image editor node,
|
|
6
|
+
* including canvas dimensions, elements, and crop settings.
|
|
7
|
+
*/
|
|
8
|
+
export interface ImageEditorNodeConfig {
|
|
9
|
+
/** Canvas width in pixels */
|
|
10
|
+
width: number;
|
|
11
|
+
/** Canvas height in pixels */
|
|
12
|
+
height: number;
|
|
13
|
+
/** Aspect ratio string (e.g., "9:16") */
|
|
14
|
+
aspectRatio: string;
|
|
15
|
+
/** Dimension preset key */
|
|
16
|
+
dimensionPreset: DimensionPresetKey;
|
|
17
|
+
/** Elements to render */
|
|
18
|
+
elements: ImageEditorElement[];
|
|
19
|
+
/** Background type: 'image' for image input, 'color' for solid color */
|
|
20
|
+
backgroundType?: 'image' | 'color';
|
|
21
|
+
/** Background color (hex) when backgroundType is 'color' */
|
|
22
|
+
backgroundColor?: string;
|
|
23
|
+
/** How the background image fits the canvas */
|
|
24
|
+
backgroundFit?: FitMode;
|
|
25
|
+
/** Cached background image URL for consistent preview */
|
|
26
|
+
previewBackgroundUrl?: string;
|
|
27
|
+
/** Cached image URLs for image elements (keyed by inputId) */
|
|
28
|
+
previewImageUrls?: Record<string, string>;
|
|
29
|
+
/** Cached text values for text elements (keyed by textInputId) */
|
|
30
|
+
previewTextValues?: Record<string, string>;
|
|
31
|
+
/** Dynamic cropping configuration */
|
|
32
|
+
dynamicCrop?: DynamicCropConfig;
|
|
33
|
+
}
|
|
34
|
+
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
35
|
+
imageEditor: {
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
aspectRatio: string;
|
|
39
|
+
dimensionPreset: string;
|
|
40
|
+
backgroundType: string;
|
|
41
|
+
elements: never[];
|
|
42
|
+
};
|
|
43
|
+
outputMode: "per-input";
|
|
44
|
+
selectionMode: null;
|
|
45
|
+
}, false>;
|
|
46
|
+
export default definition;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const types_1 = require("./types");
|
|
4
|
+
const definition = (0, types_1.defineNode)({
|
|
5
|
+
nodeId: 'image-composer',
|
|
6
|
+
label: 'Image Composer',
|
|
7
|
+
description: 'Create templated images',
|
|
8
|
+
type: 'generator',
|
|
9
|
+
category: 'Generation',
|
|
10
|
+
outputModes: ['per-input', 'single'],
|
|
11
|
+
selectionModes: null,
|
|
12
|
+
defaults: {
|
|
13
|
+
imageEditor: {
|
|
14
|
+
width: 1080,
|
|
15
|
+
height: 1920,
|
|
16
|
+
aspectRatio: '9:16',
|
|
17
|
+
dimensionPreset: '9:16',
|
|
18
|
+
backgroundType: 'image',
|
|
19
|
+
elements: [],
|
|
20
|
+
},
|
|
21
|
+
outputMode: 'per-input',
|
|
22
|
+
selectionMode: null,
|
|
23
|
+
},
|
|
24
|
+
computePorts: ({ config }) => {
|
|
25
|
+
const editorConfig = config?.imageEditor;
|
|
26
|
+
const inputs = [];
|
|
27
|
+
if (editorConfig) {
|
|
28
|
+
// Add background input if backgroundType is not 'color'
|
|
29
|
+
if (editorConfig.backgroundType !== 'color') {
|
|
30
|
+
inputs.push({
|
|
31
|
+
id: 'background',
|
|
32
|
+
type: 'image',
|
|
33
|
+
isArray: false,
|
|
34
|
+
required: true,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// Add inputs for each element with inputId or textInputId
|
|
38
|
+
editorConfig.elements.forEach(elem => {
|
|
39
|
+
if (elem.type === 'image' && elem.inputId) {
|
|
40
|
+
inputs.push({
|
|
41
|
+
id: elem.inputId,
|
|
42
|
+
type: 'image',
|
|
43
|
+
isArray: false,
|
|
44
|
+
required: true,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (elem.type === 'text' && elem.textInputId) {
|
|
48
|
+
inputs.push({
|
|
49
|
+
id: elem.textInputId,
|
|
50
|
+
type: 'text',
|
|
51
|
+
isArray: false,
|
|
52
|
+
required: true,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Build enum options from element IDs for crop boundary inputs
|
|
57
|
+
const elementEnumOptions = editorConfig.elements.map(elem => ({
|
|
58
|
+
label: elem.id,
|
|
59
|
+
value: elem.id,
|
|
60
|
+
}));
|
|
61
|
+
// Add crop boundary inputs as enum type (not required)
|
|
62
|
+
const addedCropInputs = new Set();
|
|
63
|
+
const cropConfig = editorConfig.dynamicCrop;
|
|
64
|
+
[
|
|
65
|
+
cropConfig?.vertical?.startBoundary?.inputRef,
|
|
66
|
+
cropConfig?.vertical?.endBoundary?.inputRef,
|
|
67
|
+
cropConfig?.horizontal?.startBoundary?.inputRef,
|
|
68
|
+
cropConfig?.horizontal?.endBoundary?.inputRef,
|
|
69
|
+
].forEach(inputRef => {
|
|
70
|
+
if (inputRef && !addedCropInputs.has(inputRef)) {
|
|
71
|
+
addedCropInputs.add(inputRef);
|
|
72
|
+
inputs.push({
|
|
73
|
+
id: inputRef,
|
|
74
|
+
type: 'enum',
|
|
75
|
+
isArray: false,
|
|
76
|
+
required: false,
|
|
77
|
+
enumOptions: elementEnumOptions,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
inputs,
|
|
84
|
+
outputs: [
|
|
85
|
+
{
|
|
86
|
+
id: 'output',
|
|
87
|
+
type: 'image',
|
|
88
|
+
isArray: false,
|
|
89
|
+
required: true,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
resolvePreview: (config) => {
|
|
95
|
+
const editorConfig = config?.imageEditor;
|
|
96
|
+
if (!editorConfig)
|
|
97
|
+
return null;
|
|
98
|
+
const sources = {};
|
|
99
|
+
const textContent = {};
|
|
100
|
+
// Add background URL if available
|
|
101
|
+
if (editorConfig.previewBackgroundUrl) {
|
|
102
|
+
sources['background'] = editorConfig.previewBackgroundUrl;
|
|
103
|
+
}
|
|
104
|
+
// Resolve image elements: inputId -> element.id
|
|
105
|
+
// Resolve text elements: textInputId -> element.id
|
|
106
|
+
for (const elem of editorConfig.elements) {
|
|
107
|
+
if (elem.type === 'image' && elem.inputId) {
|
|
108
|
+
const url = editorConfig.previewImageUrls?.[elem.inputId];
|
|
109
|
+
if (url) {
|
|
110
|
+
sources[elem.id] = url;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (elem.type === 'text' && elem.textInputId) {
|
|
114
|
+
const text = editorConfig.previewTextValues?.[elem.textInputId];
|
|
115
|
+
if (text) {
|
|
116
|
+
textContent[elem.id] = text;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
renderConfig: {
|
|
122
|
+
elements: editorConfig.elements,
|
|
123
|
+
width: editorConfig.width,
|
|
124
|
+
height: editorConfig.height,
|
|
125
|
+
backgroundType: editorConfig.backgroundType,
|
|
126
|
+
backgroundColor: editorConfig.backgroundColor,
|
|
127
|
+
backgroundFit: editorConfig.backgroundFit,
|
|
128
|
+
dynamicCrop: editorConfig.dynamicCrop,
|
|
129
|
+
},
|
|
130
|
+
sources,
|
|
131
|
+
textContent,
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
exports.default = definition;
|