ugcinc 4.1.55 → 4.1.56
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.
|
@@ -7,17 +7,58 @@ export interface CustomModelNodeOutputs {
|
|
|
7
7
|
output: ImageValue | VideoValue | AudioValue;
|
|
8
8
|
}
|
|
9
9
|
export type CustomModelOutputType = 'image' | 'video' | 'audio';
|
|
10
|
+
export type CustomModelParamType = 'string' | 'number' | 'boolean' | 'image' | 'video' | 'audio';
|
|
10
11
|
export interface CustomModelInputParam {
|
|
11
12
|
name: string;
|
|
12
|
-
type:
|
|
13
|
+
type: CustomModelParamType;
|
|
13
14
|
required: boolean;
|
|
14
15
|
description?: string;
|
|
15
16
|
default?: unknown;
|
|
16
17
|
}
|
|
18
|
+
export interface OpenAPIProperty {
|
|
19
|
+
type?: string;
|
|
20
|
+
format?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
default?: unknown;
|
|
23
|
+
enum?: string[];
|
|
24
|
+
items?: {
|
|
25
|
+
type?: string;
|
|
26
|
+
$ref?: string;
|
|
27
|
+
};
|
|
28
|
+
$ref?: string;
|
|
29
|
+
}
|
|
30
|
+
interface OpenAPISchemaDefinition {
|
|
31
|
+
properties?: Record<string, OpenAPIProperty>;
|
|
32
|
+
required?: string[];
|
|
33
|
+
'x-fal-order-properties'?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface OpenAPISchema {
|
|
36
|
+
components?: {
|
|
37
|
+
schemas?: Record<string, OpenAPISchemaDefinition>;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Map OpenAPI type to our param type
|
|
42
|
+
*/
|
|
43
|
+
export declare function mapOpenAPIType(prop: OpenAPIProperty, name: string): CustomModelParamType;
|
|
44
|
+
/**
|
|
45
|
+
* Parse OpenAPI schema to get input parameters
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseOpenAPIInputs(schema: OpenAPISchema): CustomModelInputParam[];
|
|
48
|
+
/**
|
|
49
|
+
* Parse OpenAPI schema to determine the output URL path.
|
|
50
|
+
* Returns a path like "images[0].url", "video.url", "audio.url", etc.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseOpenAPIOutputPath(schema: OpenAPISchema, outputType: CustomModelOutputType): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Determine output type from fal.ai category string
|
|
55
|
+
*/
|
|
56
|
+
export declare function getOutputTypeFromCategory(category?: string): CustomModelOutputType;
|
|
17
57
|
declare const definition: import("./types").NodeDefinition<"generator", {
|
|
18
58
|
modelId: string;
|
|
19
59
|
modelName: string;
|
|
20
60
|
outputType: CustomModelOutputType;
|
|
61
|
+
outputUrlPath: string | null;
|
|
21
62
|
inputParams: CustomModelInputParam[];
|
|
22
63
|
apiKey: string | undefined;
|
|
23
64
|
outputMode: OutputMode;
|
|
@@ -1,7 +1,180 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapOpenAPIType = mapOpenAPIType;
|
|
4
|
+
exports.parseOpenAPIInputs = parseOpenAPIInputs;
|
|
5
|
+
exports.parseOpenAPIOutputPath = parseOpenAPIOutputPath;
|
|
6
|
+
exports.getOutputTypeFromCategory = getOutputTypeFromCategory;
|
|
3
7
|
const types_1 = require("./types");
|
|
4
8
|
// =============================================================================
|
|
9
|
+
// OpenAPI Parsing Functions
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/** Helper types that should be excluded when searching for Input/Output schemas */
|
|
12
|
+
const HELPER_TYPES = ['File', 'QueueStatus', 'HTTPValidationError', 'ValidationError', 'Image', 'Video', 'Audio'];
|
|
13
|
+
/**
|
|
14
|
+
* Find the input schema from OpenAPI components.
|
|
15
|
+
* fal.ai names input schemas like "WanProImageToVideoInput" not just "Input"
|
|
16
|
+
*/
|
|
17
|
+
function findInputSchema(schemas) {
|
|
18
|
+
if (!schemas)
|
|
19
|
+
return null;
|
|
20
|
+
// First try exact "Input" name
|
|
21
|
+
if (schemas.Input)
|
|
22
|
+
return schemas.Input;
|
|
23
|
+
// Find schema that ends with "Input" (excluding helper types)
|
|
24
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
25
|
+
if (name.endsWith('Input') && !HELPER_TYPES.includes(name)) {
|
|
26
|
+
return schema;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Find the output schema from OpenAPI components.
|
|
33
|
+
* fal.ai names output schemas like "WanProImageToVideoOutput" not just "Output"
|
|
34
|
+
*/
|
|
35
|
+
function findOutputSchema(schemas) {
|
|
36
|
+
if (!schemas)
|
|
37
|
+
return null;
|
|
38
|
+
// First try exact "Output" name
|
|
39
|
+
if (schemas.Output)
|
|
40
|
+
return schemas.Output;
|
|
41
|
+
// Find schema that ends with "Output" (excluding helper types)
|
|
42
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
43
|
+
if (name.endsWith('Output') && !HELPER_TYPES.includes(name)) {
|
|
44
|
+
return schema;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Map OpenAPI type to our param type
|
|
51
|
+
*/
|
|
52
|
+
function mapOpenAPIType(prop, name) {
|
|
53
|
+
// Check for common image/video/audio input patterns
|
|
54
|
+
const nameLower = name.toLowerCase();
|
|
55
|
+
const descLower = (prop.description ?? '').toLowerCase();
|
|
56
|
+
if (nameLower.includes('image') || descLower.includes('image url')) {
|
|
57
|
+
return 'image';
|
|
58
|
+
}
|
|
59
|
+
if (nameLower.includes('video') || descLower.includes('video url')) {
|
|
60
|
+
return 'video';
|
|
61
|
+
}
|
|
62
|
+
if (nameLower.includes('audio') || descLower.includes('audio url')) {
|
|
63
|
+
return 'audio';
|
|
64
|
+
}
|
|
65
|
+
// Check format
|
|
66
|
+
if (prop.format === 'uri' || prop.format === 'binary') {
|
|
67
|
+
// Generic file input - assume image
|
|
68
|
+
return 'image';
|
|
69
|
+
}
|
|
70
|
+
// Map basic types
|
|
71
|
+
if (prop.type === 'integer' || prop.type === 'number') {
|
|
72
|
+
return 'number';
|
|
73
|
+
}
|
|
74
|
+
if (prop.type === 'boolean') {
|
|
75
|
+
return 'boolean';
|
|
76
|
+
}
|
|
77
|
+
return 'string';
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse OpenAPI schema to get input parameters
|
|
81
|
+
*/
|
|
82
|
+
function parseOpenAPIInputs(schema) {
|
|
83
|
+
const schemas = schema.components?.schemas;
|
|
84
|
+
const inputSchema = findInputSchema(schemas);
|
|
85
|
+
if (!inputSchema?.properties) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const params = [];
|
|
89
|
+
for (const [name, prop] of Object.entries(inputSchema.properties)) {
|
|
90
|
+
// Skip complex nested objects and arrays (for now)
|
|
91
|
+
if (prop.type === 'object' || (prop.type === 'array' && !prop.items)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
params.push({
|
|
95
|
+
name,
|
|
96
|
+
type: mapOpenAPIType(prop, name),
|
|
97
|
+
required: inputSchema.required?.includes(name) ?? false,
|
|
98
|
+
description: prop.description,
|
|
99
|
+
default: prop.default,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// Sort: required first, then prompt/text inputs, then others
|
|
103
|
+
return params.sort((a, b) => {
|
|
104
|
+
if (a.required !== b.required)
|
|
105
|
+
return a.required ? -1 : 1;
|
|
106
|
+
if (a.name === 'prompt')
|
|
107
|
+
return -1;
|
|
108
|
+
if (b.name === 'prompt')
|
|
109
|
+
return 1;
|
|
110
|
+
return a.name.localeCompare(b.name);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Parse OpenAPI schema to determine the output URL path.
|
|
115
|
+
* Returns a path like "images[0].url", "video.url", "audio.url", etc.
|
|
116
|
+
*/
|
|
117
|
+
function parseOpenAPIOutputPath(schema, outputType) {
|
|
118
|
+
const schemas = schema.components?.schemas;
|
|
119
|
+
const outputSchema = findOutputSchema(schemas);
|
|
120
|
+
if (!outputSchema?.properties) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const props = outputSchema.properties;
|
|
124
|
+
// Check for common output patterns based on output type
|
|
125
|
+
if (outputType === 'image') {
|
|
126
|
+
// Array patterns: images, outputs
|
|
127
|
+
if (props.images?.type === 'array')
|
|
128
|
+
return 'images[0].url';
|
|
129
|
+
if (props.outputs?.type === 'array')
|
|
130
|
+
return 'outputs[0].url';
|
|
131
|
+
// Object patterns: image, output
|
|
132
|
+
if (props.image)
|
|
133
|
+
return 'image.url';
|
|
134
|
+
if (props.output?.type === 'string')
|
|
135
|
+
return 'output';
|
|
136
|
+
}
|
|
137
|
+
if (outputType === 'video') {
|
|
138
|
+
// Object patterns: video
|
|
139
|
+
if (props.video)
|
|
140
|
+
return 'video.url';
|
|
141
|
+
// Array patterns: videos
|
|
142
|
+
if (props.videos?.type === 'array')
|
|
143
|
+
return 'videos[0].url';
|
|
144
|
+
if (props.output?.type === 'string')
|
|
145
|
+
return 'output';
|
|
146
|
+
}
|
|
147
|
+
if (outputType === 'audio') {
|
|
148
|
+
// Object patterns: audio, audio_file
|
|
149
|
+
if (props.audio)
|
|
150
|
+
return 'audio.url';
|
|
151
|
+
if (props.audio_file)
|
|
152
|
+
return 'audio_file.url';
|
|
153
|
+
// String patterns: audio_url
|
|
154
|
+
if (props.audio_url?.type === 'string')
|
|
155
|
+
return 'audio_url';
|
|
156
|
+
if (props.output?.type === 'string')
|
|
157
|
+
return 'output';
|
|
158
|
+
}
|
|
159
|
+
// Fallback: check for generic url property
|
|
160
|
+
if (props.url?.type === 'string')
|
|
161
|
+
return 'url';
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Determine output type from fal.ai category string
|
|
166
|
+
*/
|
|
167
|
+
function getOutputTypeFromCategory(category) {
|
|
168
|
+
if (!category)
|
|
169
|
+
return 'image';
|
|
170
|
+
const catLower = category.toLowerCase();
|
|
171
|
+
if (catLower.includes('video'))
|
|
172
|
+
return 'video';
|
|
173
|
+
if (catLower.includes('audio') || catLower.includes('speech'))
|
|
174
|
+
return 'audio';
|
|
175
|
+
return 'image';
|
|
176
|
+
}
|
|
177
|
+
// =============================================================================
|
|
5
178
|
// Node Definition
|
|
6
179
|
// =============================================================================
|
|
7
180
|
const definition = (0, types_1.defineNode)({
|
|
@@ -16,6 +189,7 @@ const definition = (0, types_1.defineNode)({
|
|
|
16
189
|
modelId: '',
|
|
17
190
|
modelName: '',
|
|
18
191
|
outputType: 'image',
|
|
192
|
+
outputUrlPath: null,
|
|
19
193
|
inputParams: [],
|
|
20
194
|
apiKey: undefined,
|
|
21
195
|
outputMode: 'per-input',
|
|
@@ -120,6 +120,7 @@ export declare const nodeDefinitions: {
|
|
|
120
120
|
modelId: string;
|
|
121
121
|
modelName: string;
|
|
122
122
|
outputType: import("./custom-model").CustomModelOutputType;
|
|
123
|
+
outputUrlPath: string | null;
|
|
123
124
|
inputParams: import("./custom-model").CustomModelInputParam[];
|
|
124
125
|
apiKey: string | undefined;
|
|
125
126
|
outputMode: import("./types").OutputMode;
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,8 @@ export type { BranchNodeConfig, BranchDefinition, BranchPassthroughInput, Branch
|
|
|
43
43
|
export type { CollectNodeConfig, CollectedValues } from './automations/nodes/collect';
|
|
44
44
|
export type { ComposeWorkflowNodeConfig } from './automations/nodes/compose-workflow';
|
|
45
45
|
export type { CreateDmNodeConfig, CreateDmMessage, DmPlatform, } from './automations/nodes/create-dm';
|
|
46
|
-
export type { CustomModelNodeConfig, CustomModelOutputType, CustomModelInputParam, } from './automations/nodes/custom-model';
|
|
46
|
+
export type { CustomModelNodeConfig, CustomModelOutputType, CustomModelInputParam, CustomModelParamType, OpenAPISchema, OpenAPIProperty, } from './automations/nodes/custom-model';
|
|
47
|
+
export { mapOpenAPIType, parseOpenAPIInputs, parseOpenAPIOutputPath, getOutputTypeFromCategory, } from './automations/nodes/custom-model';
|
|
47
48
|
export type { DeduplicateNodeConfig } from './automations/nodes/deduplicate';
|
|
48
49
|
export type { DestructureNodeConfig, DestructureNodeInputs, DestructureNodeOutputs, DestructureSelection, IndexExpression, } from './automations/nodes/destructure';
|
|
49
50
|
export { indexExpressionToIndexes, resolvePath } from './automations/nodes/destructure';
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.extractWorkflowConfig = exports.generateNodeName = exports.shuffleNodePreview = exports.getPreviewValue = exports.removePreviewForConnection = exports.updatePreviewMapForConnection = exports.computePreviewMap = exports.computeAllNodePreviews = exports.resolveNodePreview = exports.getWorkflowOutputSchema = exports.hasMissingTerminalError = exports.hasMissingTriggerError = exports.getPortErrorsForNode = exports.getErrorNodeIds = exports.validateWorkflow = exports.checkCrossContextViolation = exports.getForEachContext = exports.getConnectedSource = exports.cleanupStaleConnections = exports.removeNodeConnections = exports.removeConnection = exports.addConnection = exports.deriveConnections = exports.createNode = exports.getOutputSchema = exports.getNodeByType = exports.getAllNodes = exports.getInputPreviewValue = exports.computeAllNodePortsWithPreviews = exports.computeAllNodePorts = exports.computePortsWithPreviews = exports.computePortsForNode = exports.areTypesCompatible = exports.submitIMessageDmRenderJob = exports.submitInstagramDmRenderJob = exports.submitAutoCaptionRenderJob = exports.submitScreenshotAnimationRenderJob = exports.submitDeduplicationJob = exports.getRenderJobStatus = exports.submitVideoRenderJob = exports.submitImageRenderJob = exports.CommentsClient = exports.MediaClient = exports.AutomationsClient = exports.OrganizationClient = exports.StatsClient = exports.PostsClient = exports.TasksClient = exports.AccountsClient = exports.UGCClient = void 0;
|
|
9
|
-
exports.prepareVideoComposerInput = exports.LLMProviders = exports.IfLogicOperators = exports.resolvePath = exports.indexExpressionToIndexes = exports.nodeConfigToCaptionStyle = exports.prepareImageComposerInput = exports.processTemplate = exports.extractTemplateVariables = exports.PortIdSchema = exports.normalizeToPortId = exports.portIdToTitle = exports.isValidPortId = exports.portId = exports.selectFromPool = exports.getModelDurations = exports.getModelAspectRatios = exports.ALL_VIDEO_MODELS = exports.isImageToVideoModel = exports.IMAGE_ASPECT_RATIOS = exports.ALL_IMAGE_MODELS = exports.isEditModel = exports.getNodeDefinition = exports.isPortType = exports.formatPortType = exports.isAsyncExecutor = exports.internalNodeTypes = exports.nodeDefinitions = void 0;
|
|
9
|
+
exports.prepareVideoComposerInput = exports.LLMProviders = exports.IfLogicOperators = exports.resolvePath = exports.indexExpressionToIndexes = exports.getOutputTypeFromCategory = exports.parseOpenAPIOutputPath = exports.parseOpenAPIInputs = exports.mapOpenAPIType = exports.nodeConfigToCaptionStyle = exports.prepareImageComposerInput = exports.processTemplate = exports.extractTemplateVariables = exports.PortIdSchema = exports.normalizeToPortId = exports.portIdToTitle = exports.isValidPortId = exports.portId = exports.selectFromPool = exports.getModelDurations = exports.getModelAspectRatios = exports.ALL_VIDEO_MODELS = exports.isImageToVideoModel = exports.IMAGE_ASPECT_RATIOS = exports.ALL_IMAGE_MODELS = exports.isEditModel = exports.getNodeDefinition = exports.isPortType = exports.formatPortType = exports.isAsyncExecutor = exports.internalNodeTypes = exports.nodeDefinitions = void 0;
|
|
10
10
|
// =============================================================================
|
|
11
11
|
// Client Exports
|
|
12
12
|
// =============================================================================
|
|
@@ -124,6 +124,11 @@ var image_composer_1 = require("./automations/nodes/image-composer");
|
|
|
124
124
|
Object.defineProperty(exports, "prepareImageComposerInput", { enumerable: true, get: function () { return image_composer_1.prepareImageComposerInput; } });
|
|
125
125
|
var auto_caption_1 = require("./automations/nodes/auto-caption");
|
|
126
126
|
Object.defineProperty(exports, "nodeConfigToCaptionStyle", { enumerable: true, get: function () { return auto_caption_1.nodeConfigToCaptionStyle; } });
|
|
127
|
+
var custom_model_1 = require("./automations/nodes/custom-model");
|
|
128
|
+
Object.defineProperty(exports, "mapOpenAPIType", { enumerable: true, get: function () { return custom_model_1.mapOpenAPIType; } });
|
|
129
|
+
Object.defineProperty(exports, "parseOpenAPIInputs", { enumerable: true, get: function () { return custom_model_1.parseOpenAPIInputs; } });
|
|
130
|
+
Object.defineProperty(exports, "parseOpenAPIOutputPath", { enumerable: true, get: function () { return custom_model_1.parseOpenAPIOutputPath; } });
|
|
131
|
+
Object.defineProperty(exports, "getOutputTypeFromCategory", { enumerable: true, get: function () { return custom_model_1.getOutputTypeFromCategory; } });
|
|
127
132
|
var destructure_1 = require("./automations/nodes/destructure");
|
|
128
133
|
Object.defineProperty(exports, "indexExpressionToIndexes", { enumerable: true, get: function () { return destructure_1.indexExpressionToIndexes; } });
|
|
129
134
|
Object.defineProperty(exports, "resolvePath", { enumerable: true, get: function () { return destructure_1.resolvePath; } });
|