ugcinc 3.88.5 → 4.0.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.
@@ -3,11 +3,11 @@ import { BaseClient } from './base';
3
3
  /**
4
4
  * Check if two port types are compatible for connection
5
5
  * A connection is valid if:
6
- * 1. The types match exactly, OR
7
- * 2. The source is an array type and target is 'object', OR
8
- * 3. The source is a PortType[] and includes the target type, OR
9
- * 4. The target is a PortType[] and includes the source type, OR
10
- * 5. Both are PortType[] and have at least one common type
6
+ * 1. The types match exactly (same base type and same isArray), OR
7
+ * 2. The source is an array type and target is 'object' (non-array), OR
8
+ * 3. The source is a PortType[] and includes a compatible type, OR
9
+ * 4. The target is a PortType[] and includes a compatible type, OR
10
+ * 5. Both are PortType[] and have at least one common compatible type
11
11
  *
12
12
  * Note: Array inputs are strict - they only accept exact matches
13
13
  */
@@ -5,36 +5,40 @@ exports.areTypesCompatible = areTypesCompatible;
5
5
  exports.getAllNodes = getAllNodes;
6
6
  exports.getNodeByType = getNodeByType;
7
7
  exports.getOutputSchema = getOutputSchema;
8
+ const types_1 = require("./types");
8
9
  const base_1 = require("./base");
9
10
  /**
10
- * Array types for collections
11
+ * Helper to check if a PortType or array of PortTypes is an array
12
+ * Used internally to normalize port types for comparison
11
13
  */
12
- const ARRAY_TYPES = ['image[]', 'video[]', 'audio[]', 'text[]', 'object[]', 'account[]', 'social_audio[]', 'boolean[]'];
14
+ function isPortTypeArray(pt) {
15
+ return Array.isArray(pt) && pt.length > 0 && typeof pt[0] === 'object' && 'type' in pt[0];
16
+ }
13
17
  /**
14
18
  * Check if two port types are compatible for connection
15
19
  * A connection is valid if:
16
- * 1. The types match exactly, OR
17
- * 2. The source is an array type and target is 'object', OR
18
- * 3. The source is a PortType[] and includes the target type, OR
19
- * 4. The target is a PortType[] and includes the source type, OR
20
- * 5. Both are PortType[] and have at least one common type
20
+ * 1. The types match exactly (same base type and same isArray), OR
21
+ * 2. The source is an array type and target is 'object' (non-array), OR
22
+ * 3. The source is a PortType[] and includes a compatible type, OR
23
+ * 4. The target is a PortType[] and includes a compatible type, OR
24
+ * 5. Both are PortType[] and have at least one common compatible type
21
25
  *
22
26
  * Note: Array inputs are strict - they only accept exact matches
23
27
  */
24
28
  function areTypesCompatible({ sourceType, targetType, }) {
25
- const sourceTypes = Array.isArray(sourceType) ? sourceType : [sourceType];
26
- const targetTypes = Array.isArray(targetType) ? targetType : [targetType];
29
+ const sourceTypes = isPortTypeArray(sourceType) ? sourceType : [sourceType];
30
+ const targetTypes = isPortTypeArray(targetType) ? targetType : [targetType];
27
31
  return sourceTypes.some(st => {
28
32
  return targetTypes.some(tt => {
29
- // Exact match
30
- if (st === tt)
33
+ // Exact match (same base type and same isArray)
34
+ if (st.type === tt.type && st.isArray === tt.isArray)
31
35
  return true;
32
- // Object inputs accept any array type (backwards compatibility with for-each, etc.)
33
- if (tt === 'object' && ARRAY_TYPES.includes(st)) {
36
+ // Object inputs (non-array) accept any array type (backwards compatibility with for-each, etc.)
37
+ if (tt.type === 'object' && !tt.isArray && st.isArray) {
34
38
  return true;
35
39
  }
36
40
  // Array inputs are strict - no other compatibility
37
- if (ARRAY_TYPES.includes(tt)) {
41
+ if (tt.isArray) {
38
42
  return false;
39
43
  }
40
44
  return false;
@@ -271,14 +275,14 @@ function getAllNodes() {
271
275
  inputs: [
272
276
  {
273
277
  id: "url",
274
- type: "text",
278
+ type: (0, types_1.portType)('text'),
275
279
  required: true,
276
280
  },
277
281
  ],
278
282
  outputs: [
279
283
  {
280
284
  id: "video",
281
- type: "video",
285
+ type: (0, types_1.portType)('video'),
282
286
  required: true,
283
287
  },
284
288
  ],
@@ -293,7 +297,7 @@ function getAllNodes() {
293
297
  outputs: [
294
298
  {
295
299
  id: "account",
296
- type: "account",
300
+ type: (0, types_1.portType)('account'),
297
301
  required: true,
298
302
  },
299
303
  ],
@@ -308,7 +312,7 @@ function getAllNodes() {
308
312
  outputs: [
309
313
  {
310
314
  id: "text",
311
- type: "text",
315
+ type: (0, types_1.portType)('text'),
312
316
  required: true,
313
317
  },
314
318
  ],
@@ -323,14 +327,14 @@ function getAllNodes() {
323
327
  inputs: [
324
328
  {
325
329
  id: "background",
326
- type: "image",
330
+ type: (0, types_1.portType)('image'),
327
331
  required: true,
328
332
  },
329
333
  ],
330
334
  outputs: [
331
335
  {
332
336
  id: "output",
333
- type: "image",
337
+ type: (0, types_1.portType)('image'),
334
338
  required: true,
335
339
  },
336
340
  ],
@@ -345,7 +349,7 @@ function getAllNodes() {
345
349
  outputs: [
346
350
  {
347
351
  id: "output",
348
- type: "video",
352
+ type: (0, types_1.portType)('video'),
349
353
  required: true,
350
354
  },
351
355
  ],
@@ -369,19 +373,19 @@ function getAllNodes() {
369
373
  inputs: [
370
374
  {
371
375
  id: "media",
372
- type: ["video", "audio"],
376
+ type: [(0, types_1.portType)('video'), (0, types_1.portType)('audio')],
373
377
  required: true,
374
378
  },
375
379
  ],
376
380
  outputs: [
377
381
  {
378
382
  id: "text",
379
- type: "text",
383
+ type: (0, types_1.portType)('text'),
380
384
  required: true,
381
385
  },
382
386
  {
383
387
  id: "segments",
384
- type: "object",
388
+ type: (0, types_1.portType)('object'),
385
389
  required: true,
386
390
  itemSchema: {
387
391
  text: { type: 'string' },
@@ -400,14 +404,14 @@ function getAllNodes() {
400
404
  inputs: [
401
405
  {
402
406
  id: "video",
403
- type: "video",
407
+ type: (0, types_1.portType)('video'),
404
408
  required: true,
405
409
  },
406
410
  ],
407
411
  outputs: [
408
412
  {
409
413
  id: "output",
410
- type: "video",
414
+ type: (0, types_1.portType)('video'),
411
415
  required: true,
412
416
  },
413
417
  ],
@@ -421,14 +425,14 @@ function getAllNodes() {
421
425
  inputs: [
422
426
  {
423
427
  id: "image",
424
- type: "image",
428
+ type: (0, types_1.portType)('image'),
425
429
  required: true,
426
430
  },
427
431
  ],
428
432
  outputs: [
429
433
  {
430
434
  id: "output",
431
- type: "video",
435
+ type: (0, types_1.portType)('video'),
432
436
  required: true,
433
437
  },
434
438
  ],
@@ -447,7 +451,7 @@ function getAllNodes() {
447
451
  outputs: [
448
452
  {
449
453
  id: "output",
450
- type: "image",
454
+ type: (0, types_1.portType)('image'),
451
455
  required: true,
452
456
  },
453
457
  ],
@@ -461,14 +465,14 @@ function getAllNodes() {
461
465
  inputs: [
462
466
  {
463
467
  id: "video",
464
- type: "video",
468
+ type: (0, types_1.portType)('video'),
465
469
  required: true,
466
470
  },
467
471
  ],
468
472
  outputs: [
469
473
  {
470
474
  id: "output",
471
- type: "video",
475
+ type: (0, types_1.portType)('video'),
472
476
  required: true,
473
477
  },
474
478
  ],
@@ -494,7 +498,7 @@ function getAllNodes() {
494
498
  inputs: [
495
499
  {
496
500
  id: "prompt",
497
- type: "text",
501
+ type: (0, types_1.portType)('text'),
498
502
  required: true,
499
503
  },
500
504
  // Image input is dynamically added for image-to-video models
@@ -502,7 +506,7 @@ function getAllNodes() {
502
506
  outputs: [
503
507
  {
504
508
  id: "output",
505
- type: "video",
509
+ type: (0, types_1.portType)('video'),
506
510
  required: true,
507
511
  },
508
512
  ],
@@ -516,7 +520,7 @@ function getAllNodes() {
516
520
  inputs: [
517
521
  {
518
522
  id: "prompt",
519
- type: "text",
523
+ type: (0, types_1.portType)('text'),
520
524
  required: true,
521
525
  },
522
526
  // Image input is dynamically added for edit models
@@ -524,7 +528,7 @@ function getAllNodes() {
524
528
  outputs: [
525
529
  {
526
530
  id: "output",
527
- type: "image",
531
+ type: (0, types_1.portType)('image'),
528
532
  required: true,
529
533
  },
530
534
  ],
@@ -550,7 +554,7 @@ function getAllNodes() {
550
554
  inputs: [
551
555
  {
552
556
  id: "array",
553
- type: ["image[]", "video[]", "audio[]", "text[]", "object[]"],
557
+ type: [(0, types_1.portType)('image', true), (0, types_1.portType)('video', true), (0, types_1.portType)('audio', true), (0, types_1.portType)('text', true), (0, types_1.portType)('object', true)],
554
558
  required: true,
555
559
  },
556
560
  ],
@@ -596,14 +600,14 @@ function getAllNodes() {
596
600
  inputs: [
597
601
  {
598
602
  id: "input",
599
- type: "boolean",
603
+ type: (0, types_1.portType)('boolean'),
600
604
  required: true,
601
605
  },
602
606
  ],
603
607
  outputs: [
604
608
  {
605
609
  id: "output",
606
- type: "boolean",
610
+ type: (0, types_1.portType)('boolean'),
607
611
  required: false,
608
612
  },
609
613
  ],
@@ -631,7 +635,7 @@ function getAllNodes() {
631
635
  inputs: [
632
636
  {
633
637
  id: "key",
634
- type: "text",
638
+ type: (0, types_1.portType)('text'),
635
639
  required: true,
636
640
  },
637
641
  ],
@@ -649,7 +653,7 @@ function getAllNodes() {
649
653
  inputs: [
650
654
  {
651
655
  id: "value",
652
- type: ["image", "video", "audio", "text", "object", "boolean", "number"],
656
+ type: [(0, types_1.portType)('image'), (0, types_1.portType)('video'), (0, types_1.portType)('audio'), (0, types_1.portType)('text'), (0, types_1.portType)('object'), (0, types_1.portType)('boolean'), (0, types_1.portType)('number')],
653
657
  required: true,
654
658
  },
655
659
  ],
@@ -657,7 +661,7 @@ function getAllNodes() {
657
661
  outputs: [
658
662
  {
659
663
  id: "array",
660
- type: ["image[]", "video[]", "audio[]", "text[]", "object[]"],
664
+ type: [(0, types_1.portType)('image', true), (0, types_1.portType)('video', true), (0, types_1.portType)('audio', true), (0, types_1.portType)('text', true), (0, types_1.portType)('object', true)],
661
665
  required: true,
662
666
  },
663
667
  ],
@@ -672,7 +676,7 @@ function getAllNodes() {
672
676
  inputs: [
673
677
  {
674
678
  id: "array",
675
- type: ["image[]", "video[]", "audio[]", "text[]", "object[]"],
679
+ type: [(0, types_1.portType)('image', true), (0, types_1.portType)('video', true), (0, types_1.portType)('audio', true), (0, types_1.portType)('text', true), (0, types_1.portType)('object', true)],
676
680
  required: true,
677
681
  },
678
682
  ],
@@ -692,17 +696,17 @@ function getAllNodes() {
692
696
  inputs: [
693
697
  {
694
698
  id: "account",
695
- type: "account",
699
+ type: (0, types_1.portType)('account'),
696
700
  required: true,
697
701
  },
698
702
  {
699
703
  id: "caption",
700
- type: "text",
704
+ type: (0, types_1.portType)('text'),
701
705
  required: false,
702
706
  },
703
707
  {
704
708
  id: "social-audio",
705
- type: "social_audio",
709
+ type: (0, types_1.portType)('social_audio'),
706
710
  required: false,
707
711
  },
708
712
  ],
@@ -727,7 +731,7 @@ function getAllNodes() {
727
731
  inputs: [
728
732
  {
729
733
  id: "result",
730
- type: ["image", "video", "audio", "text", "social_audio", "account", "boolean", "object"],
734
+ type: [(0, types_1.portType)('image'), (0, types_1.portType)('video'), (0, types_1.portType)('audio'), (0, types_1.portType)('text'), (0, types_1.portType)('social_audio'), (0, types_1.portType)('account'), (0, types_1.portType)('boolean'), (0, types_1.portType)('object')],
731
735
  required: true,
732
736
  },
733
737
  ],
package/dist/index.d.ts CHANGED
@@ -21,4 +21,4 @@ export { MediaClient } from './media';
21
21
  export { CommentsClient } from './comments';
22
22
  export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
23
23
  export type { ClientConfig, } from './base';
24
- export type { SuccessResponse, ErrorResponse, ApiResponse, Account, AccountStat, AccountTask, EditProfileInfo, Task, TaskType, Post, PostType, PostStatus, PostStat, ApiKey, EditorConfig, VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, TimeMode, SegmentTimelinePosition, ImageEditorNodeConfig, ImageEditorElement, ImageEditorNodeInput, ImageEditorNodeOutput, VideoEditorNodeInput, DimensionPresetKey, EditorChannel, TimeValue, DeduplicationInput, BaseSegmentProps, VisualSegmentProps, EditorSegment, VideoSegment, AudioSegment, ImageSegment, TextSegment, StaticSegment, PositionAnchor, RelativePositionConfig, GetAccountsParams, GetAccountStatsParams, GetAccountStatusParams, UpdateAccountInfoParams, UpdateAccountSocialParams, GetTasksParams, GetPostsParams, CreateSlideshowParams, GetPostStatsParams, GetPostStatusParams, CreateVideoParams, RefreshStatsParams, RefreshStatsResponse, RefreshStatsError, DailyAggregatedStat, GetDailyAggregatedStatsParams, DailyPostStat, GetDailyPostStatsParams, TopAccount, GetTopAccountsParams, TopPost, GetTopPostsParams, MediaType, NodePort, ResolvedPort, ResolvedPorts, NodeControlConfig, NodeTypeEnum, WorkflowNodeDefinition, WorkflowDefinition, CanvasState, TemplateNode, AutomationTemplate, AutomationRun, NodeRun, ExecutorNode, ExecutionEdge, OutputSchemaProperty, SelectionMode, ExhaustionBehavior, SelectionConfig, SelectionState, OutputMode, NodeOutputValues, OutputInput, OutputNodeConfig, ObjectSchemaFieldLevel3, ObjectSchemaFieldLevel2, ObjectSchemaField, ManualTriggerOutput, ManualTriggerNodeConfig, TriggerIterationMode, IterationExhaustionBehavior, CollectionSelectionMode, TriggerCollectionConfig, DayOfWeek, RecurrenceMediaOutput, RecurrenceMediaConfig, RecurrenceNodeConfig, AccountNodeConfig, MediaNodeEnabledType, RecurrenceMediaEnabledType, MediaNodeOutput, MediaNodeConfig, PostSchedulingMode, PostSchedulingConfig, AutoPostMode, AutoPostInputType, AutoPostInput, AutoPostNodeConfig, SaveToMediaInput, SaveToMediaNodeConfig, DeduplicateNodeConfig, ForEachOutputProperty, ForEachInputPort, ForEachNodeConfig, RandomValueType, RandomInputPort, RandomNodeMode, RandomNodeConfig, IfLogicOperator, IfBooleanInput, IfPassthroughInput, IfNodeConfig, RandomRouteBranch, RandomRoutePassthroughInput, RandomRouteObjectField, RandomRouteNodeConfig, BranchDefinition, BranchValueConfig, BranchPassthroughInput, BranchNodeConfig, VideoImportPlatform, VideoImportQuality, VideoImportNodeConfig, AutoCaptionPreset, AutoCaptionFontWeight, AutoCaptionPosition, AutoCaptionNodeConfig, ScreenshotAnimationNodeConfig, CreateDmMessage, CreateDmNodeConfig, DestructureSelection, DestructureNodeConfig, ImageGenerationTextModel, ImageGenerationEditModel, ImageGenerationModel, ImageGenerationNodeConfig, CustomModelParamType, CustomModelInputParam, CustomModelNodeConfig, VideoGenerationTextToVideoModel, VideoGenerationImageToVideoModel, VideoGenerationModel, VideoGenerationNodeConfig, ArrayType, PortType, LLMOutputField, LLMApiKeys, LLMNodeConfig, UserMedia, SocialAudio, Media, MediaUse, GetMediaParams, CreateSocialAudioParams, UploadMediaParams, UploadMediaResponse, UpdateMediaTagParams, DeleteMediaParams, DeleteMediaResponse, CreateMediaFromUrlParams, ImportTextParams, ImportTextResponse, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, Comment, CommentStatus, CreateCommentParams, CreateCommentResponse, GetCommentsParams, ValidationErrorType, ValidationError, ExportedNode, ExportedConnection, ExportedTemplate, AutomationExport, ExportedExecutor, ExportedEdge, ExportedRun, AutomationRunExport, AccountData, FlowControlOutput, NodeType, ExecutorContext, NodeExecutor, ExecutorAsyncJobStatus, AsyncNodeExecutor, } from './types';
24
+ export type { SuccessResponse, ErrorResponse, ApiResponse, Account, AccountStat, AccountTask, EditProfileInfo, Task, TaskType, Post, PostType, PostStatus, PostStat, ApiKey, EditorConfig, VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, TimeMode, SegmentTimelinePosition, ImageEditorNodeConfig, ImageEditorElement, ImageEditorNodeInput, ImageEditorNodeOutput, VideoEditorNodeInput, DimensionPresetKey, EditorChannel, TimeValue, DeduplicationInput, BaseSegmentProps, VisualSegmentProps, EditorSegment, VideoSegment, AudioSegment, ImageSegment, TextSegment, StaticSegment, PositionAnchor, RelativePositionConfig, GetAccountsParams, GetAccountStatsParams, GetAccountStatusParams, UpdateAccountInfoParams, UpdateAccountSocialParams, GetTasksParams, GetPostsParams, CreateSlideshowParams, GetPostStatsParams, GetPostStatusParams, CreateVideoParams, RefreshStatsParams, RefreshStatsResponse, RefreshStatsError, DailyAggregatedStat, GetDailyAggregatedStatsParams, DailyPostStat, GetDailyPostStatsParams, TopAccount, GetTopAccountsParams, TopPost, GetTopPostsParams, MediaType, NodePort, ResolvedPort, ResolvedPorts, NodeControlConfig, NodeTypeEnum, WorkflowNodeDefinition, WorkflowDefinition, CanvasState, TemplateNode, AutomationTemplate, AutomationRun, NodeRun, ExecutorNode, ExecutionEdge, OutputSchemaProperty, SelectionMode, ExhaustionBehavior, SelectionConfig, SelectionState, OutputMode, NodeOutputValues, OutputInput, OutputNodeConfig, ObjectSchemaFieldLevel3, ObjectSchemaFieldLevel2, ObjectSchemaField, ManualTriggerOutput, ManualTriggerNodeConfig, TriggerIterationMode, IterationExhaustionBehavior, CollectionSelectionMode, TriggerCollectionConfig, DayOfWeek, RecurrenceMediaOutput, RecurrenceMediaConfig, RecurrenceNodeConfig, AccountNodeConfig, MediaNodeEnabledType, RecurrenceMediaEnabledType, MediaNodeOutput, MediaNodeConfig, PostSchedulingMode, PostSchedulingConfig, AutoPostMode, AutoPostInputType, AutoPostInput, AutoPostNodeConfig, SaveToMediaInput, SaveToMediaNodeConfig, DeduplicateNodeConfig, ForEachOutputProperty, ForEachInputPort, ForEachNodeConfig, RandomValueType, RandomInputPort, RandomNodeMode, RandomNodeConfig, IfLogicOperator, IfBooleanInput, IfPassthroughInput, IfNodeConfig, RandomRouteBranch, RandomRoutePassthroughInput, RandomRouteObjectField, RandomRouteNodeConfig, BranchDefinition, BranchValueConfig, BranchPassthroughInput, BranchNodeConfig, VideoImportPlatform, VideoImportQuality, VideoImportNodeConfig, AutoCaptionPreset, AutoCaptionFontWeight, AutoCaptionPosition, AutoCaptionNodeConfig, ScreenshotAnimationNodeConfig, CreateDmMessage, CreateDmNodeConfig, DestructureSelection, DestructureNodeConfig, ImageGenerationTextModel, ImageGenerationEditModel, ImageGenerationModel, ImageGenerationNodeConfig, CustomModelParamType, CustomModelInputParam, CustomModelNodeConfig, VideoGenerationTextToVideoModel, VideoGenerationImageToVideoModel, VideoGenerationModel, VideoGenerationNodeConfig, BasePortType, PortType, portType, formatPortType, LegacyPortType, isLegacyPortType, fromLegacyPortType, toLegacyPortType, normalizePortType, normalizePortTypes, LLMOutputField, LLMApiKeys, LLMNodeConfig, UserMedia, SocialAudio, Media, MediaUse, GetMediaParams, CreateSocialAudioParams, UploadMediaParams, UploadMediaResponse, UpdateMediaTagParams, DeleteMediaParams, DeleteMediaResponse, CreateMediaFromUrlParams, ImportTextParams, ImportTextResponse, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, Comment, CommentStatus, CreateCommentParams, CreateCommentResponse, GetCommentsParams, ValidationErrorType, ValidationError, ExportedNode, ExportedConnection, ExportedTemplate, AutomationExport, ExportedExecutor, ExportedEdge, ExportedRun, AutomationRunExport, AccountData, FlowControlOutput, NodeType, ExecutorContext, NodeExecutor, ExecutorAsyncJobStatus, AsyncNodeExecutor, } from './types';
package/dist/ports.js CHANGED
@@ -11,6 +11,7 @@ exports.extractTemplateVariables = extractTemplateVariables;
11
11
  exports.computeInputPorts = computeInputPorts;
12
12
  exports.computeOutputPorts = computeOutputPorts;
13
13
  exports.isInputPortRequired = isInputPortRequired;
14
+ const types_1 = require("./types");
14
15
  const automations_1 = require("./automations");
15
16
  /**
16
17
  * Extract template variables from text (e.g., "Hello {{name}}" -> ["name"])
@@ -42,7 +43,7 @@ function computeInputPorts({ node }) {
42
43
  return baseInputs;
43
44
  return variables.map(variable => ({
44
45
  id: variable,
45
- type: 'text',
46
+ type: (0, types_1.portType)('text'),
46
47
  required: false,
47
48
  }));
48
49
  }
@@ -56,7 +57,7 @@ function computeInputPorts({ node }) {
56
57
  if (editorConfig.backgroundType !== 'color') {
57
58
  dynamicInputs.push({
58
59
  id: 'background',
59
- type: 'image',
60
+ type: (0, types_1.portType)('image'),
60
61
  required: true,
61
62
  });
62
63
  }
@@ -65,14 +66,14 @@ function computeInputPorts({ node }) {
65
66
  if (elem.type === 'image' && elem.inputId) {
66
67
  dynamicInputs.push({
67
68
  id: elem.inputId,
68
- type: 'image',
69
+ type: (0, types_1.portType)('image'),
69
70
  required: true,
70
71
  });
71
72
  }
72
73
  else if (elem.type === 'text' && elem.textInputId) {
73
74
  dynamicInputs.push({
74
75
  id: elem.textInputId,
75
- type: 'text',
76
+ type: (0, types_1.portType)('text'),
76
77
  required: true,
77
78
  });
78
79
  }
@@ -90,7 +91,7 @@ function computeInputPorts({ node }) {
90
91
  addedCropInputs.add(inputRef);
91
92
  dynamicInputs.push({
92
93
  id: inputRef,
93
- type: 'text',
94
+ type: (0, types_1.portType)('text'),
94
95
  required: false,
95
96
  });
96
97
  }
@@ -108,9 +109,9 @@ function computeInputPorts({ node }) {
108
109
  channel.segments.forEach(segment => {
109
110
  if ('inputRef' in segment && segment.inputRef && !addedIds.has(segment.inputRef)) {
110
111
  addedIds.add(segment.inputRef);
111
- const inputType = segment.type === 'video' ? 'video'
112
- : segment.type === 'audio' ? 'audio'
113
- : 'image';
112
+ const inputType = segment.type === 'video' ? (0, types_1.portType)('video')
113
+ : segment.type === 'audio' ? (0, types_1.portType)('audio')
114
+ : (0, types_1.portType)('image');
114
115
  dynamicInputs.push({
115
116
  id: segment.inputRef,
116
117
  type: inputType,
@@ -121,7 +122,7 @@ function computeInputPorts({ node }) {
121
122
  addedIds.add(segment.textInputRef);
122
123
  dynamicInputs.push({
123
124
  id: segment.textInputRef,
124
- type: 'text',
125
+ type: (0, types_1.portType)('text'),
125
126
  required: true,
126
127
  });
127
128
  }
@@ -140,11 +141,14 @@ function computeInputPorts({ node }) {
140
141
  const varName = v.name ?? v.id;
141
142
  return !passThrough[varName];
142
143
  })
143
- .map(v => ({
144
- id: v.id,
145
- type: (v.variableType === 'dropdown' ? 'text' : (v.variableType ?? 'text')),
146
- required: false,
147
- }));
144
+ .map(v => {
145
+ const varType = v.variableType === 'dropdown' ? 'text' : (v.variableType ?? 'text');
146
+ return {
147
+ id: v.id,
148
+ type: (0, types_1.portType)(varType),
149
+ required: false,
150
+ };
151
+ });
148
152
  }
149
153
  // Output nodes: generate inputs from outputConfig.inputs
150
154
  if (node.type === 'output') {
@@ -154,7 +158,7 @@ function computeInputPorts({ node }) {
154
158
  return baseInputs;
155
159
  return configInputs.map((input) => ({
156
160
  id: input.id,
157
- type: input.type,
161
+ type: (0, types_1.portType)(input.type, input.isArray ?? false),
158
162
  required: false,
159
163
  }));
160
164
  }
@@ -165,14 +169,14 @@ function computeInputPorts({ node }) {
165
169
  const dynamicInputs = [];
166
170
  if (mode === 'video') {
167
171
  // Video mode: video input required
168
- dynamicInputs.push({ id: 'video', type: 'video', required: true });
172
+ dynamicInputs.push({ id: 'video', type: (0, types_1.portType)('video'), required: true });
169
173
  }
170
174
  else {
171
175
  // Slideshow mode
172
176
  const inputType = autoPostConfig?.inputType ?? 'static';
173
177
  if (inputType === 'variable') {
174
178
  // Variable mode: single images array port
175
- dynamicInputs.push({ id: 'images', type: 'object', required: true });
179
+ dynamicInputs.push({ id: 'images', type: (0, types_1.portType)('object'), required: true });
176
180
  }
177
181
  else {
178
182
  // Static mode: individual image inputs
@@ -182,15 +186,15 @@ function computeInputPorts({ node }) {
182
186
  { id: 'image3' },
183
187
  ];
184
188
  imageInputs.forEach((input) => {
185
- dynamicInputs.push({ id: input.id, type: 'image', required: true });
189
+ dynamicInputs.push({ id: input.id, type: (0, types_1.portType)('image'), required: true });
186
190
  });
187
191
  }
188
192
  }
189
193
  // Add static inputs (same for both modes)
190
- dynamicInputs.push({ id: 'account', type: 'account', required: true }, { id: 'caption', type: 'text', required: false });
194
+ dynamicInputs.push({ id: 'account', type: (0, types_1.portType)('account'), required: true }, { id: 'caption', type: (0, types_1.portType)('text'), required: false });
191
195
  // Only add social-audio port if isVariable is true
192
196
  if (autoPostConfig?.socialAudio?.isVariable) {
193
- dynamicInputs.push({ id: 'social-audio', type: 'audio', required: false });
197
+ dynamicInputs.push({ id: 'social-audio', type: (0, types_1.portType)('audio'), required: false });
194
198
  }
195
199
  return dynamicInputs;
196
200
  }
@@ -202,7 +206,7 @@ function computeInputPorts({ node }) {
202
206
  return baseInputs;
203
207
  return configInputs.map((input) => ({
204
208
  id: input.id,
205
- type: input.type,
209
+ type: (0, types_1.portType)(input.type),
206
210
  required: true,
207
211
  }));
208
212
  }
@@ -216,13 +220,13 @@ function computeInputPorts({ node }) {
216
220
  const variables = extractTemplateVariables([systemPrompt]);
217
221
  variables.forEach(v => dynamicInputs.push({
218
222
  id: v,
219
- type: ['text', 'object', 'boolean'],
223
+ type: [(0, types_1.portType)('text'), (0, types_1.portType)('object'), (0, types_1.portType)('boolean')],
220
224
  required: true,
221
225
  }));
222
226
  // Add image input refs
223
- llmConfig?.imageInputRefs?.forEach((ref) => dynamicInputs.push({ id: ref, type: 'image', required: true }));
227
+ llmConfig?.imageInputRefs?.forEach((ref) => dynamicInputs.push({ id: ref, type: (0, types_1.portType)('image'), required: true }));
224
228
  // Add video input refs
225
- llmConfig?.videoInputRefs?.forEach((ref) => dynamicInputs.push({ id: ref, type: 'video', required: true }));
229
+ llmConfig?.videoInputRefs?.forEach((ref) => dynamicInputs.push({ id: ref, type: (0, types_1.portType)('video'), required: true }));
226
230
  return dynamicInputs.length > 0 ? dynamicInputs : baseInputs;
227
231
  }
228
232
  // For-each nodes: array input + passthrough inputs
@@ -230,10 +234,10 @@ function computeInputPorts({ node }) {
230
234
  const forEachConfig = node.config?.forEachConfig;
231
235
  const inputPorts = forEachConfig?.inputPorts ?? [];
232
236
  return [
233
- { id: 'array', type: 'object', required: true },
237
+ { id: 'array', type: (0, types_1.portType)('object'), required: true },
234
238
  ...inputPorts.map((port) => ({
235
239
  id: port.id,
236
- type: port.type,
240
+ type: (0, types_1.portType)(port.type, port.isArray ?? false),
237
241
  required: false,
238
242
  })),
239
243
  ];
@@ -252,11 +256,11 @@ function computeInputPorts({ node }) {
252
256
  }
253
257
  // Transcript nodes: media input
254
258
  if (node.type === 'transcript') {
255
- return [{ id: 'media', type: ['video', 'audio'], required: true }];
259
+ return [{ id: 'media', type: [(0, types_1.portType)('video'), (0, types_1.portType)('audio')], required: true }];
256
260
  }
257
261
  // Video import nodes: url input
258
262
  if (node.type === 'video-import') {
259
- return [{ id: 'url', type: 'text', required: true }];
263
+ return [{ id: 'url', type: (0, types_1.portType)('text'), required: true }];
260
264
  }
261
265
  // Image Generation nodes: prompt + optional image for edit models
262
266
  if (node.type === 'generate-image') {
@@ -264,10 +268,10 @@ function computeInputPorts({ node }) {
264
268
  const model = imageGenConfig?.model ?? '';
265
269
  const isEditModel = model.includes('/edit');
266
270
  const dynamicInputs = [
267
- { id: 'prompt', type: 'text', required: true },
271
+ { id: 'prompt', type: (0, types_1.portType)('text'), required: true },
268
272
  ];
269
273
  if (isEditModel) {
270
- dynamicInputs.push({ id: 'image', type: 'image', required: true });
274
+ dynamicInputs.push({ id: 'image', type: (0, types_1.portType)('image'), required: true });
271
275
  }
272
276
  return dynamicInputs;
273
277
  }
@@ -278,11 +282,12 @@ function computeInputPorts({ node }) {
278
282
  const dynamicInputs = [];
279
283
  inputParams.forEach((param) => {
280
284
  if (param.name === 'prompt' || param.type === 'image' || param.type === 'video' || param.type === 'audio') {
285
+ const pType = (param.type === 'image' || param.type === 'video' || param.type === 'audio')
286
+ ? param.type
287
+ : 'text';
281
288
  dynamicInputs.push({
282
289
  id: param.name,
283
- type: (param.type === 'image' || param.type === 'video' || param.type === 'audio'
284
- ? param.type
285
- : 'text'),
290
+ type: (0, types_1.portType)(pType),
286
291
  required: param.required,
287
292
  });
288
293
  }
@@ -291,7 +296,7 @@ function computeInputPorts({ node }) {
291
296
  }
292
297
  // Deduplicate nodes: video input
293
298
  if (node.type === 'deduplicate') {
294
- return [{ id: 'video', type: 'video', required: true }];
299
+ return [{ id: 'video', type: (0, types_1.portType)('video'), required: true }];
295
300
  }
296
301
  return baseInputs;
297
302
  }
package/dist/types.d.ts CHANGED
@@ -758,13 +758,55 @@ export type StaticSegment = ImageSegment | TextSegment;
758
758
  */
759
759
  export type MediaType = 'video' | 'image' | 'audio' | 'text';
760
760
  /**
761
- * Array types for collections
761
+ * Base port type - all possible value types without array modifier
762
762
  */
763
- export type ArrayType = 'image[]' | 'video[]' | 'audio[]' | 'text[]' | 'object[]' | 'account[]' | 'social_audio[]' | 'boolean[]';
763
+ export type BasePortType = 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'object' | 'account' | 'date' | 'social_audio';
764
764
  /**
765
- * Extended port types (includes non-media types for special nodes)
765
+ * Structured port type descriptor
766
+ * Replaces string-based types like 'image[]' with explicit { type, isArray }
766
767
  */
767
- export type PortType = MediaType | 'number' | 'boolean' | 'object' | 'account' | 'date' | 'social_audio' | ArrayType;
768
+ export interface PortType {
769
+ type: BasePortType;
770
+ isArray: boolean;
771
+ }
772
+ /**
773
+ * Helper to create a PortType descriptor
774
+ */
775
+ export declare function portType(type: BasePortType, isArray?: boolean): PortType;
776
+ /**
777
+ * Format a PortType for display (e.g., { type: 'image', isArray: true } -> 'image[]')
778
+ */
779
+ export declare function formatPortType(port: PortType): string;
780
+ /**
781
+ * @deprecated Legacy string-based port type. Use PortType interface instead.
782
+ * Kept for backwards compatibility with existing saved automations.
783
+ */
784
+ export type LegacyPortType = 'image' | 'video' | 'audio' | 'text' | 'number' | 'boolean' | 'object' | 'account' | 'date' | 'social_audio' | 'image[]' | 'video[]' | 'audio[]' | 'text[]' | 'number[]' | 'boolean[]' | 'object[]' | 'account[]' | 'social_audio[]';
785
+ /**
786
+ * @deprecated Check if a value is a legacy string port type.
787
+ * Use for runtime detection during migration.
788
+ */
789
+ export declare function isLegacyPortType(value: unknown): value is LegacyPortType;
790
+ /**
791
+ * @deprecated Convert legacy string port type to structured PortType.
792
+ * Use for migrating old code and data.
793
+ */
794
+ export declare function fromLegacyPortType(legacy: LegacyPortType): PortType;
795
+ /**
796
+ * @deprecated Convert structured PortType to legacy string format.
797
+ * Use only for backwards compatibility with systems expecting string types.
798
+ */
799
+ export declare function toLegacyPortType(port: PortType): LegacyPortType;
800
+ /**
801
+ * @deprecated Normalize port type - accepts either legacy string or structured format,
802
+ * always returns structured PortType. Use at read boundaries during migration.
803
+ */
804
+ export declare function normalizePortType(value: LegacyPortType | PortType): PortType;
805
+ /**
806
+ * @deprecated Normalize an array of port types or a single port type.
807
+ * Handles PortType | PortType[] | LegacyPortType | LegacyPortType[] formats.
808
+ */
809
+ export declare function normalizePortTypes(value: LegacyPortType | PortType | LegacyPortType[] | PortType[]): PortType | PortType[];
768
810
  /**
769
811
  * Selection order configuration for media nodes
770
812
  */
package/dist/types.js CHANGED
@@ -1,9 +1,76 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NodeTypes = void 0;
4
+ exports.portType = portType;
5
+ exports.formatPortType = formatPortType;
6
+ exports.isLegacyPortType = isLegacyPortType;
7
+ exports.fromLegacyPortType = fromLegacyPortType;
8
+ exports.toLegacyPortType = toLegacyPortType;
9
+ exports.normalizePortType = normalizePortType;
10
+ exports.normalizePortTypes = normalizePortTypes;
4
11
  exports.isEditModel = isEditModel;
5
12
  exports.isImageToVideoModel = isImageToVideoModel;
6
13
  exports.isAsyncExecutor = isAsyncExecutor;
14
+ /**
15
+ * Helper to create a PortType descriptor
16
+ */
17
+ function portType(type, isArray = false) {
18
+ return { type, isArray };
19
+ }
20
+ /**
21
+ * Format a PortType for display (e.g., { type: 'image', isArray: true } -> 'image[]')
22
+ */
23
+ function formatPortType(port) {
24
+ return port.isArray ? `${port.type}[]` : port.type;
25
+ }
26
+ /**
27
+ * @deprecated Check if a value is a legacy string port type.
28
+ * Use for runtime detection during migration.
29
+ */
30
+ function isLegacyPortType(value) {
31
+ if (typeof value !== 'string')
32
+ return false;
33
+ const baseTypes = ['image', 'video', 'audio', 'text', 'number', 'boolean', 'object', 'account', 'date', 'social_audio'];
34
+ const arrayTypes = baseTypes.map(t => `${t}[]`);
35
+ return baseTypes.includes(value) || arrayTypes.includes(value);
36
+ }
37
+ /**
38
+ * @deprecated Convert legacy string port type to structured PortType.
39
+ * Use for migrating old code and data.
40
+ */
41
+ function fromLegacyPortType(legacy) {
42
+ if (legacy.endsWith('[]')) {
43
+ return { type: legacy.slice(0, -2), isArray: true };
44
+ }
45
+ return { type: legacy, isArray: false };
46
+ }
47
+ /**
48
+ * @deprecated Convert structured PortType to legacy string format.
49
+ * Use only for backwards compatibility with systems expecting string types.
50
+ */
51
+ function toLegacyPortType(port) {
52
+ return (port.isArray ? `${port.type}[]` : port.type);
53
+ }
54
+ /**
55
+ * @deprecated Normalize port type - accepts either legacy string or structured format,
56
+ * always returns structured PortType. Use at read boundaries during migration.
57
+ */
58
+ function normalizePortType(value) {
59
+ if (typeof value === 'string') {
60
+ return fromLegacyPortType(value);
61
+ }
62
+ return value;
63
+ }
64
+ /**
65
+ * @deprecated Normalize an array of port types or a single port type.
66
+ * Handles PortType | PortType[] | LegacyPortType | LegacyPortType[] formats.
67
+ */
68
+ function normalizePortTypes(value) {
69
+ if (Array.isArray(value)) {
70
+ return value.map(v => normalizePortType(v));
71
+ }
72
+ return normalizePortType(value);
73
+ }
7
74
  /**
8
75
  * Type guard to check if model is an edit/inpaint model
9
76
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc",
3
- "version": "3.88.5",
3
+ "version": "4.0.0",
4
4
  "description": "TypeScript/JavaScript client for the UGC Inc API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",