ugcinc 4.1.95 → 4.1.97

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.
@@ -331,6 +331,7 @@ export declare function getPortErrorsForNode({ nodeId, errors, }: {
331
331
  }>;
332
332
  /**
333
333
  * Check if there's a missing trigger error
334
+ * @deprecated Trigger validation has been removed - automations no longer require trigger nodes
334
335
  */
335
336
  export declare function hasMissingTriggerError({ errors }: {
336
337
  errors: ValidationError[];
@@ -485,6 +485,7 @@ function getAllNodes() {
485
485
  outputModes: def.outputModes,
486
486
  selectionModes: def.selectionModes,
487
487
  defaults: def.defaults,
488
+ hidden: def.hidden,
488
489
  });
489
490
  }
490
491
  return results;
@@ -731,7 +732,6 @@ function checkCrossContextViolation({ sourceNodeId, targetNodeId, nodes, }) {
731
732
  // ===========================================================================
732
733
  // Workflow Validation
733
734
  // ===========================================================================
734
- const TRIGGER_TYPES = ['manual-trigger', 'recurrence'];
735
735
  const TERMINAL_TYPES = ['passthrough', 'auto-post', 'save-to-media'];
736
736
  /**
737
737
  * Validate workflow and return structured errors for UI highlighting
@@ -739,15 +739,7 @@ const TERMINAL_TYPES = ['passthrough', 'auto-post', 'save-to-media'];
739
739
  function validateWorkflow({ nodes, }) {
740
740
  const errors = [];
741
741
  const connections = deriveConnectionsInternal(nodes);
742
- // 1. Check for trigger node
743
- const hasTrigger = nodes.some(n => TRIGGER_TYPES.includes(n.type));
744
- if (!hasTrigger) {
745
- errors.push({
746
- type: 'missing_trigger',
747
- message: 'Automation requires a trigger node (Manual Trigger or Recurrence)',
748
- });
749
- }
750
- // 2. Check for terminal node
742
+ // 1. Check for terminal node
751
743
  const hasTerminal = nodes.some(n => TERMINAL_TYPES.includes(n.type));
752
744
  if (!hasTerminal) {
753
745
  errors.push({
@@ -1024,8 +1016,10 @@ function getPortErrorsForNode({ nodeId, errors, }) {
1024
1016
  }
1025
1017
  /**
1026
1018
  * Check if there's a missing trigger error
1019
+ * @deprecated Trigger validation has been removed - automations no longer require trigger nodes
1027
1020
  */
1028
1021
  function hasMissingTriggerError({ errors }) {
1022
+ // Trigger validation removed - kept for backward compatibility
1029
1023
  return errors.some(e => e.type === 'missing_trigger');
1030
1024
  }
1031
1025
  /**
@@ -328,6 +328,14 @@ export declare const nodeDefinitions: {
328
328
  __TInputs: import("./transcript").TranscriptNodeInputs;
329
329
  __TOutputs: import("./transcript").TranscriptNodeOutputs;
330
330
  };
331
+ readonly variable: NodeDefinition<"variable", "source", {
332
+ outputs: import("../types").NodePort[];
333
+ outputMode: import("./types").OutputMode | null;
334
+ selectionMode: import("./types").SelectionMode | null;
335
+ }, import("./variable").VariableNodeInputs, import("./variable").VariableNodeOutputs, false> & {
336
+ __TInputs: import("./variable").VariableNodeInputs;
337
+ __TOutputs: import("./variable").VariableNodeOutputs;
338
+ };
331
339
  readonly 'video-composer': NodeDefinition<"video-composer", "generator", {
332
340
  videoEditor: {
333
341
  width: number;
@@ -39,6 +39,7 @@ const screenshot_animation_1 = __importDefault(require("./screenshot-animation")
39
39
  const social_audio_1 = __importDefault(require("./social-audio"));
40
40
  const text_1 = __importDefault(require("./text"));
41
41
  const transcript_1 = __importDefault(require("./transcript"));
42
+ const variable_1 = __importDefault(require("./variable"));
42
43
  const video_composer_1 = __importDefault(require("./video-composer"));
43
44
  const video_import_1 = __importDefault(require("./video-import"));
44
45
  // =============================================================================
@@ -77,6 +78,7 @@ exports.nodeDefinitions = {
77
78
  'social-audio': social_audio_1.default,
78
79
  'text': text_1.default,
79
80
  'transcript': transcript_1.default,
81
+ 'variable': variable_1.default,
80
82
  'video-composer': video_composer_1.default,
81
83
  'video-import': video_import_1.default,
82
84
  };
@@ -10,6 +10,7 @@ const definition = (0, types_1.defineNode)({
10
10
  description: 'Trigger manually',
11
11
  type: 'trigger',
12
12
  category: 'Triggers',
13
+ hidden: true,
13
14
  outputModes: null,
14
15
  selectionModes: null,
15
16
  defaults: {
@@ -1,11 +1,11 @@
1
- import type { NodePort, PortValue } from '../types';
1
+ import type { NodePort, PortValue, DayOfWeek } from '../types';
2
2
  import { type TriggerCollectionConfig, type MediaItemType, type OutputMode, type SelectionMode } from './types';
3
3
  /** Recurrence node has no inputs (trigger node) */
4
4
  export interface RecurrenceNodeInputs {
5
5
  }
6
6
  /** Recurrence outputs are dynamic based on config. Output port IDs are user-defined. */
7
7
  export type RecurrenceNodeOutputs = Record<string, PortValue | PortValue[]>;
8
- export type DayOfWeek = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
8
+ export type { DayOfWeek } from '../types';
9
9
  export interface RecurrenceMediaOutput extends NodePort {
10
10
  type: MediaItemType;
11
11
  selectionMode: 'specific' | 'by-tag';
@@ -11,6 +11,7 @@ const definition = (0, types_1.defineNode)({
11
11
  description: 'Run continuously',
12
12
  type: 'trigger',
13
13
  category: 'Triggers',
14
+ hidden: true,
14
15
  outputModes: null,
15
16
  selectionModes: null,
16
17
  defaults: {
@@ -159,6 +159,8 @@ export interface NodeDefinition<TNodeId extends string, T extends NodeCategory,
159
159
  isFlowControl: boolean;
160
160
  /** If true, this node can be "captured" by a for-each context */
161
161
  canBeCaptured: boolean;
162
+ /** If true, this node is hidden from the add node UI */
163
+ hidden: boolean;
162
164
  outputModes: OutputModesForCategory<T>;
163
165
  selectionModes: SelectionModesForCategory<T>;
164
166
  defaults: DefaultsForCategory<T, TDefaults>;
@@ -255,6 +257,8 @@ export declare function defineNode<TNodeId extends string, T extends NodeCategor
255
257
  isFlowControl?: boolean;
256
258
  /** If true, this node can be "captured" by a for-each context */
257
259
  canBeCaptured?: boolean;
260
+ /** If true, this node is hidden from the add node UI */
261
+ hidden?: boolean;
258
262
  outputModes: OutputModesForCategory<T>;
259
263
  selectionModes: SelectionModesForCategory<T>;
260
264
  defaults: DefaultsForCategory<T, TCustomDefaults>;
@@ -35,6 +35,7 @@ function defineNode(def) {
35
35
  isInternal: (def.isInternal ?? false),
36
36
  isFlowControl: def.isFlowControl ?? false,
37
37
  canBeCaptured: def.canBeCaptured ?? false,
38
+ hidden: def.hidden ?? false,
38
39
  /**
39
40
  * Wrapper that accepts a node (type + config) and calls the typed computePorts.
40
41
  * Runtime validates node.type matches this definition.
@@ -0,0 +1,18 @@
1
+ import type { NodePort, PortValue } from '../types';
2
+ import { type OutputMode, type SelectionMode } from './types';
3
+ /** Variable node has no inputs (source node) */
4
+ export interface VariableNodeInputs {
5
+ }
6
+ /** Variable outputs are dynamic based on config. Output port IDs are user-defined. */
7
+ export type VariableNodeOutputs = Record<string, PortValue | PortValue[]>;
8
+ declare const definition: import("./types").NodeDefinition<"variable", "source", {
9
+ outputs: NodePort[];
10
+ outputMode: OutputMode | null;
11
+ selectionMode: SelectionMode | null;
12
+ }, VariableNodeInputs, VariableNodeOutputs, false>;
13
+ declare const _default: typeof definition & {
14
+ __TInputs: VariableNodeInputs;
15
+ __TOutputs: VariableNodeOutputs;
16
+ };
17
+ export default _default;
18
+ export type VariableNodeConfig = typeof definition.defaults;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const types_1 = require("./types");
4
+ // =============================================================================
5
+ // Node Definition
6
+ // =============================================================================
7
+ const definition = (0, types_1.defineNode)({
8
+ nodeId: 'variable',
9
+ label: 'Variable',
10
+ description: 'Define runtime input variables',
11
+ type: 'source',
12
+ category: 'Sources',
13
+ outputModes: ['single', 'per-input'],
14
+ selectionModes: ['random', 'sequential'],
15
+ defaults: {
16
+ outputs: [{ id: 'input-1', type: 'image', isArray: false, required: true }],
17
+ outputMode: 'single',
18
+ selectionMode: 'random',
19
+ },
20
+ computePorts: ({ config }) => {
21
+ return {
22
+ inputs: [],
23
+ outputs: config?.outputs ?? [],
24
+ };
25
+ },
26
+ generatePreview: (config, _ctx) => {
27
+ // Variable outputs are provided at runtime, no preview available
28
+ const result = {};
29
+ for (const output of config.outputs) {
30
+ result[output.id] = null;
31
+ }
32
+ return (0, types_1.preview)(result);
33
+ },
34
+ validate: (config) => {
35
+ const errors = [];
36
+ const outputs = config.outputs;
37
+ if (!outputs?.length) {
38
+ errors.push('Variable node requires at least one output to be configured');
39
+ }
40
+ else {
41
+ const validTypes = ['image', 'video', 'audio', 'text', 'social_audio', 'account', 'boolean', 'object'];
42
+ for (const output of outputs) {
43
+ if (!output.id) {
44
+ errors.push('Variable output requires an id');
45
+ }
46
+ const outputType = Array.isArray(output.type) ? output.type.join(' | ') : output.type;
47
+ if (!output.type || !validTypes.includes(outputType)) {
48
+ errors.push(`Invalid Variable output type: ${outputType}`);
49
+ }
50
+ }
51
+ }
52
+ return errors;
53
+ },
54
+ });
55
+ exports.default = definition;
@@ -267,6 +267,8 @@ export interface ComputedNode {
267
267
  selectionModes: SelectionMode[] | null;
268
268
  /** Default config values for this node */
269
269
  defaults: Record<string, unknown>;
270
+ /** If true, this node is hidden from the add node UI */
271
+ hidden?: boolean;
270
272
  }
271
273
  export interface OutputSchemaProperty {
272
274
  type: 'string' | 'number' | 'boolean' | 'array' | 'object';
@@ -353,6 +355,31 @@ type InternalTemplateNode = {
353
355
  * Discriminated union enabling automatic type narrowing based on node type.
354
356
  */
355
357
  export type TemplateNode = UserCreatableTemplateNode | InternalTemplateNode;
358
+ export type DayOfWeek = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
359
+ /**
360
+ * Schedule configuration for automated runs (stored on template, not recurrence node)
361
+ */
362
+ export interface ScheduleConfig {
363
+ frequencyType: 'per-day' | 'periodic';
364
+ runsPerDay?: number;
365
+ periodDays?: number;
366
+ daysOfWeek?: DayOfWeek[];
367
+ timingType: 'specific' | 'random-window';
368
+ specificTimes?: string[];
369
+ randomWindowStart?: string;
370
+ randomWindowEnd?: string;
371
+ timezone: string;
372
+ }
373
+ /**
374
+ * Account iteration configuration for scheduled runs
375
+ */
376
+ export interface AccountIterationConfig {
377
+ enabled: boolean;
378
+ selectionMode: 'specific' | 'by-tag';
379
+ accountIds?: string[];
380
+ accountTag?: string;
381
+ iterationMode: 'sequential' | 'random';
382
+ }
356
383
  export interface AutomationTemplate {
357
384
  id: string;
358
385
  org_id: string;
@@ -365,6 +392,8 @@ export interface AutomationTemplate {
365
392
  recurrence_enabled: boolean;
366
393
  next_run_at: string | null;
367
394
  last_run_at: string | null;
395
+ schedule_config: ScheduleConfig | null;
396
+ account_iteration_config: AccountIterationConfig | null;
368
397
  created_at: string;
369
398
  updated_at: string;
370
399
  }
package/dist/index.d.ts CHANGED
@@ -56,12 +56,14 @@ export { IfLogicOperators, applyLogicOperator } from './automations/nodes/if';
56
56
  export type { LLMNodeConfig, LLMNodeOutputs, LLMProvider, LLMApiKeys, } from './automations/nodes/llm';
57
57
  export { LLMProviders, outputFieldToZod, outputFieldsToZod } from './automations/nodes/llm';
58
58
  export type { ManualTriggerNodeConfig, ManualTriggerNodeOutputs } from './automations/nodes/manual-trigger';
59
+ export type { VariableNodeConfig, VariableNodeOutputs } from './automations/nodes/variable';
59
60
  export type { MediaNodeConfig, MediaNodeOutput } from './automations/nodes/media';
60
61
  export type { NotNodeConfig } from './automations/nodes/not';
61
62
  export type { OutputNodeConfig, OutputNodeOutputs } from './automations/nodes/output';
62
63
  export type { RandomNodeConfig, RandomInputPort, RandomNodeMode, RandomNodeOutputs } from './automations/nodes/random';
63
64
  export type { RandomRouteNodeConfig, RandomRouteBranch, RandomRoutePassthroughInput, } from './automations/nodes/random-route';
64
- export type { RecurrenceNodeConfig, DayOfWeek, RecurrenceMediaOutput, RecurrenceMediaConfig, RecurrenceNodeOutputs, } from './automations/nodes/recurrence';
65
+ export type { RecurrenceNodeConfig, RecurrenceMediaOutput, RecurrenceMediaConfig, RecurrenceNodeOutputs, } from './automations/nodes/recurrence';
66
+ export type { DayOfWeek, ScheduleConfig, AccountIterationConfig, } from './automations/types';
65
67
  export type { SaveToMediaNodeConfig, SaveToMediaInput, SaveToMediaType } from './automations/nodes/save-to-media';
66
68
  export { formatDateTag } from './automations/nodes/save-to-media';
67
69
  export type { ScreenshotAnimationNodeConfig } from './automations/nodes/screenshot-animation';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc",
3
- "version": "4.1.95",
3
+ "version": "4.1.97",
4
4
  "description": "TypeScript/JavaScript client for the UGC Inc API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",