ugcinc 4.5.91 → 4.5.93

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.
@@ -846,10 +846,52 @@ function validateWorkflow({ nodes, }) {
846
846
  }
847
847
  }
848
848
  }
849
- // 7. Check for circular dependencies
849
+ // 7. Check for duplicate port names across input nodes
850
+ const inputPortSeen = new Map(); // portName -> first nodeId
851
+ for (const node of nodes) {
852
+ if (node.type !== 'input')
853
+ continue;
854
+ const outputs = node.config.outputs ?? [];
855
+ for (const output of outputs) {
856
+ const existing = inputPortSeen.get(output.id);
857
+ if (existing) {
858
+ errors.push({
859
+ type: 'duplicate_port_name',
860
+ nodeId: node.id,
861
+ portId: output.id,
862
+ message: `Duplicate input port name '${output.id}' — each input port must have a unique name across all input nodes`,
863
+ });
864
+ }
865
+ else {
866
+ inputPortSeen.set(output.id, node.id);
867
+ }
868
+ }
869
+ }
870
+ // 8. Check for duplicate port names across output (passthrough) nodes
871
+ const outputPortSeen = new Map(); // portName -> first nodeId
872
+ for (const node of nodes) {
873
+ if (node.type !== 'passthrough')
874
+ continue;
875
+ const inputs = node.config.inputs ?? [];
876
+ for (const input of inputs) {
877
+ const existing = outputPortSeen.get(input.id);
878
+ if (existing) {
879
+ errors.push({
880
+ type: 'duplicate_port_name',
881
+ nodeId: node.id,
882
+ portId: input.id,
883
+ message: `Duplicate output port name '${input.id}' — each output port must have a unique name across all output nodes`,
884
+ });
885
+ }
886
+ else {
887
+ outputPortSeen.set(input.id, node.id);
888
+ }
889
+ }
890
+ }
891
+ // 9. Check for circular dependencies
850
892
  const circularErrors = detectCircularDependencies(nodes);
851
893
  errors.push(...circularErrors);
852
- // 8. Check for for-each context boundary violations
894
+ // 10. Check for for-each context boundary violations
853
895
  const boundaryErrors = validateForEachContextBoundaries(nodes);
854
896
  errors.push(...boundaryErrors);
855
897
  return errors;
@@ -10,12 +10,22 @@ export interface HeaderEntry {
10
10
  key: string;
11
11
  value: string;
12
12
  }
13
+ export type ApiRequestOutputPrimitiveType = 'string' | 'number' | 'boolean' | 'image';
14
+ export type ApiRequestArrayItemType = ApiRequestOutputPrimitiveType | 'object';
15
+ export type ApiRequestOutputType = ApiRequestOutputPrimitiveType | 'object' | 'array';
16
+ export interface ApiRequestOutputField {
17
+ name: string;
18
+ type: ApiRequestOutputType;
19
+ items?: ApiRequestArrayItemType;
20
+ objectSchema?: ObjectSchemaField[];
21
+ required?: boolean;
22
+ }
13
23
  declare const definition: import("./types").NodeDefinition<"api-request", "generator", {
14
24
  url: string;
15
25
  method: HttpMethod;
16
26
  headers: HeaderEntry[];
17
27
  body: string;
18
- outputFields: ObjectSchemaField[];
28
+ outputFields: ApiRequestOutputField[];
19
29
  outputMode: OutputMode;
20
30
  selectionMode: SelectionMode | null;
21
31
  }, ApiRequestNodeInputs, ApiRequestNodeOutputs, false>;
@@ -8,6 +8,41 @@ const types_1 = require("./types");
8
8
  // =============================================================================
9
9
  const HttpMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
10
10
  exports.HttpMethods = HttpMethods;
11
+ function getArrayItemPortType(items) {
12
+ switch (items) {
13
+ case 'number':
14
+ return 'number';
15
+ case 'boolean':
16
+ return 'boolean';
17
+ case 'object':
18
+ return 'object';
19
+ case 'image':
20
+ return 'image';
21
+ default:
22
+ return 'text';
23
+ }
24
+ }
25
+ function getOutputPortShape(field) {
26
+ if (field.type === 'array') {
27
+ return {
28
+ type: getArrayItemPortType(field.items),
29
+ isArray: true,
30
+ };
31
+ }
32
+ if (field.type === 'object') {
33
+ return { type: 'object', isArray: false };
34
+ }
35
+ if (field.type === 'number') {
36
+ return { type: 'number', isArray: false };
37
+ }
38
+ if (field.type === 'boolean') {
39
+ return { type: 'boolean', isArray: false };
40
+ }
41
+ if (field.type === 'image') {
42
+ return { type: 'image', isArray: false };
43
+ }
44
+ return { type: 'text', isArray: false };
45
+ }
11
46
  // =============================================================================
12
47
  // Node Definition
13
48
  // =============================================================================
@@ -15,7 +50,7 @@ const definition = (0, types_1.defineNode)({
15
50
  nodeId: 'api-request',
16
51
  label: 'API Request',
17
52
  description: 'Make HTTP requests to external APIs',
18
- guide: 'Makes HTTP requests to external APIs and returns parsed response data. Use when you need to fetch data from or send data to external services. Configure URL, method (GET/POST/PUT/PATCH/DELETE), headers, and body. Supports template variables ({{var}}) in URL, header values, and body for dynamic values from upstream nodes. Define output fields to extract specific data from JSON responses. Use cases: fetching external data, triggering webhooks, integrating third-party APIs, sending data to external services.',
53
+ guide: 'Makes HTTP requests to external APIs and returns parsed response data. Use when you need to fetch data from or send data to external services. Configure URL, method (GET/POST/PUT/PATCH/DELETE), headers, and body. Supports template variables ({{var}}) in URL, header values, and body for dynamic values from upstream nodes. Define output fields to extract specific data from JSON responses, including typed arrays and image URL fields that should flow into image ports. Use cases: fetching external data, triggering webhooks, integrating third-party APIs, sending data to external services.',
19
54
  type: 'generator',
20
55
  category: 'Generation',
21
56
  outputModes: ['per-input', 'single'],
@@ -49,32 +84,11 @@ const definition = (0, types_1.defineNode)({
49
84
  // Output ports from outputFields
50
85
  const outputFields = (config?.outputFields ?? [{ name: 'response', type: 'string' }]);
51
86
  const outputs = outputFields.map(f => {
52
- let pType;
53
- let pIsArray;
54
- if (f.type === 'array') {
55
- pType = f.items === 'object' ? 'object' : 'text';
56
- pIsArray = true;
57
- }
58
- else if (f.type === 'object') {
59
- pType = 'object';
60
- pIsArray = false;
61
- }
62
- else if (f.type === 'number') {
63
- pType = 'number';
64
- pIsArray = false;
65
- }
66
- else if (f.type === 'boolean') {
67
- pType = 'boolean';
68
- pIsArray = false;
69
- }
70
- else {
71
- pType = 'text';
72
- pIsArray = false;
73
- }
87
+ const { type, isArray } = getOutputPortShape(f);
74
88
  return {
75
89
  id: f.name,
76
- type: pType,
77
- isArray: pIsArray,
90
+ type,
91
+ isArray,
78
92
  required: f.required ?? true,
79
93
  ...(f.objectSchema && { objectSchema: f.objectSchema }),
80
94
  };
@@ -18,7 +18,7 @@ export declare const nodeDefinitions: {
18
18
  method: import("./api-request").HttpMethod;
19
19
  headers: import("./api-request").HeaderEntry[];
20
20
  body: string;
21
- outputFields: import("./types").ObjectSchemaField[];
21
+ outputFields: import("./api-request").ApiRequestOutputField[];
22
22
  outputMode: import("./types").OutputMode;
23
23
  selectionMode: import("./types").SelectionMode | null;
24
24
  }, import("./api-request").ApiRequestNodeInputs, import("./api-request").ApiRequestNodeOutputs, false> & {
@@ -538,7 +538,7 @@ export declare function isAsyncExecutor(executor: AnyNodeExecutor | AnyAsyncNode
538
538
  /**
539
539
  * Validation error types for automation workflows
540
540
  */
541
- export type ValidationErrorType = 'missing_trigger' | 'missing_terminal' | 'missing_required_input' | 'type_mismatch' | 'empty_media_pool' | 'empty_account_pool' | 'circular_dependency' | 'for_each_boundary_violation' | 'invalid_node_config';
541
+ export type ValidationErrorType = 'missing_trigger' | 'missing_terminal' | 'missing_required_input' | 'type_mismatch' | 'empty_media_pool' | 'empty_account_pool' | 'circular_dependency' | 'for_each_boundary_violation' | 'invalid_node_config' | 'duplicate_port_name';
542
542
  /**
543
543
  * Structured validation error with location info for UI highlighting
544
544
  */
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export type { ClientConfig } from './base';
28
28
  export type { Account, AccountStat, AccountTask, EditProfileInfo, GetAccountsParams, GetAccountStatsParams, GetAccountStatusParams, AccountInfoUpdate, UpdateAccountInfoParams, AccountInfoUpdateResult, UpdateAccountInfoResponse, AccountSocialUpdate, UpdateAccountSocialParams, AccountSocialUpdateResult, UpdateAccountSocialResponse, DeleteAccountPostsParams, DeleteAccountPostsResponse, ResetWarmupParams, ResetWarmupResponse, NicheSwitchUpdate, NicheSwitchParams, NicheSwitchResult, NicheSwitchResponse, CreateAccountInput, CreateAccountsParams, CreateAccountResult, CreateAccountsResponse, TroubleshootFailReason, TroubleshootAccount, TroubleshootParams, } from './accounts';
29
29
  export type { TaskType, Task, GetTasksParams } from './tasks';
30
30
  export type { PostType, PostStatus, Post, PostStat, GetPostsParams, CreateDraftParams, CreateSlideshowParams, GetPostStatsParams, GetPostStatusParams, CreateVideoParams, UpdatePostParams, DeletePostsParams, DeletePostsResponse, RetryPostsParams, SetPostStatusParams, SetPostStatusResponse, PreviewScheduleEntry, PreviewScheduleParams, PreviewScheduleResult, } from './posts';
31
- export type { RefreshStatsParams, RefreshStatsError, RefreshStatsResponse, RefreshStartEvent, RefreshProgressEvent, RefreshDoneEvent, RefreshStreamEvent, DailyAggregatedStat, GetDailyAggregatedStatsParams, DailyAccountStat, GetDailyAccountStatsParams, DailyPostStat, GetDailyPostStatsParams, DashboardDailyStat, GetDashboardDailyStatsParams, TopAccount, GetTopAccountsParams, TopPost, GetTopPostsParams, } from './stats';
31
+ export type { RefreshStatsParams, RefreshStatsError, RefreshStatsResponse, RefreshStatsProgressResponse, RefreshStartEvent, RefreshProgressEvent, RefreshDoneEvent, RefreshStreamEvent, DailyAggregatedStat, GetDailyAggregatedStatsParams, DailyAccountStat, GetDailyAccountStatsParams, DailyPostStat, GetDailyPostStatsParams, DashboardDailyStat, GetDashboardDailyStatsParams, TopAccount, GetTopAccountsParams, TopPost, GetTopPostsParams, } from './stats';
32
32
  export type { Org, ApiKey, DeleteApiKeyParams, EditApiKeyParams, IntegrationKey, IntegrationProvider, UpsertIntegrationKeyParams, DeleteIntegrationKeyParams } from './org';
33
33
  export type { UserMedia, MediaUse, SocialAudio, Media, GetMediaParams, GetSocialAudioParams, UploadMediaParams, UploadMediaResponse, MediaTagUpdate, UpdateMediaTagsParams, MediaTagUpdateResult, UpdateMediaTagsResponse, UpdateMediaTagParams, UpdateMediaNameParams, DeleteMediaParams, DeleteMediaResponse, CreateSocialAudioParams, ImportTextParams, ImportTextResponse, CreateMediaFromUrlParams, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, GetUploadTokenParams, UploadTokenResponse, } from './media';
34
34
  export type { CommentStatus, Comment, CreateCommentParams, CreateCommentResponse, GetCommentsParams, } from './comments';
@@ -38,7 +38,7 @@ export type { VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, Vid
38
38
  export type { ImageEditorNodeConfig, ImageComposerNodeConfig, ImageComposerRenderInput } from './automations/nodes/image-composer';
39
39
  export { prepareImageComposerInput } from './automations/nodes/image-composer';
40
40
  export type { AccountNodeConfig } from './automations/nodes/account';
41
- export type { ApiRequestNodeConfig, HeaderEntry, HttpMethod } from './automations/nodes/api-request';
41
+ export type { ApiRequestNodeConfig, ApiRequestOutputField, ApiRequestOutputType, ApiRequestArrayItemType, HeaderEntry, HttpMethod, } from './automations/nodes/api-request';
42
42
  export { HttpMethods } from './automations/nodes/api-request';
43
43
  export type { AutoCaptionNodeConfig, AutoCaptionPreset, AutoCaptionFontWeight, AutoCaptionPosition, } from './automations/nodes/auto-caption';
44
44
  export { nodeConfigToCaptionStyle } from './automations/nodes/auto-caption';
package/dist/stats.d.ts CHANGED
@@ -12,11 +12,23 @@ export interface RefreshStatsError {
12
12
  error: string;
13
13
  }
14
14
  export interface RefreshStatsResponse {
15
- accounts_refreshed: number;
16
- accounts_failed: number;
17
- total_accounts: number;
18
- post_stats_count: number;
19
- errors?: RefreshStatsError[];
15
+ batchId: string;
16
+ batchCreatedAtMs: number;
17
+ queuedAccounts: number;
18
+ totalAccounts: number;
19
+ totalPosts: number;
20
+ }
21
+ export interface RefreshStatsProgressResponse {
22
+ batchId: string;
23
+ batchCreatedAtMs: number;
24
+ totalAccounts: number;
25
+ completedAccounts: number;
26
+ failedAccounts: number;
27
+ activeAccounts: number;
28
+ queuedAccounts: number;
29
+ done: boolean;
30
+ totalPosts: number;
31
+ completedPosts: number;
20
32
  }
21
33
  export interface DailyAggregatedStat {
22
34
  date: Date | string;
@@ -358,6 +370,10 @@ export declare class StatsClient extends BaseClient {
358
370
  * Note: Can only be called once per hour per organization (or per org_group if specified)
359
371
  */
360
372
  refresh(params?: RefreshStatsParams): Promise<ApiResponse<RefreshStatsResponse>>;
373
+ getRefreshProgress(params: {
374
+ batchId: string;
375
+ org_group?: string;
376
+ }): Promise<ApiResponse<RefreshStatsProgressResponse>>;
361
377
  /**
362
378
  * Refresh stats with NDJSON streaming progress.
363
379
  * Returns the raw Response so the caller can read the stream.
package/dist/stats.js CHANGED
@@ -209,6 +209,13 @@ class StatsClient extends base_1.BaseClient {
209
209
  async refresh(params) {
210
210
  return this.post('/stats/refresh', params ?? {});
211
211
  }
212
+ async getRefreshProgress(params) {
213
+ const searchParams = new URLSearchParams({ batchId: params.batchId });
214
+ if (params.org_group) {
215
+ searchParams.set('org_group', params.org_group);
216
+ }
217
+ return this.get(`/stats/refresh/progress?${searchParams.toString()}`);
218
+ }
212
219
  /**
213
220
  * Refresh stats with NDJSON streaming progress.
214
221
  * Returns the raw Response so the caller can read the stream.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc",
3
- "version": "4.5.91",
3
+ "version": "4.5.93",
4
4
  "description": "TypeScript/JavaScript client for the UGC Inc API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",