ugcinc 4.1.46 → 4.1.49

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/index.d.ts CHANGED
@@ -31,7 +31,7 @@ export type { RefreshStatsParams, RefreshStatsError, RefreshStatsResponse, Daily
31
31
  export type { ApiKey, DeleteApiKeyParams, EditApiKeyParams } from './org';
32
32
  export type { UserMedia, MediaUse, SocialAudio, Media, GetMediaParams, GetSocialAudioParams, UploadMediaParams, UploadMediaResponse, MediaTagUpdate, UpdateMediaTagsParams, MediaTagUpdateResult, UpdateMediaTagsResponse, UpdateMediaTagParams, DeleteMediaParams, DeleteMediaResponse, CreateSocialAudioParams, ImportTextParams, ImportTextResponse, CreateMediaFromUrlParams, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, GetUploadTokenParams, UploadTokenResponse, } from './media';
33
33
  export type { CommentStatus, Comment, CreateCommentParams, CreateCommentResponse, GetCommentsParams, } from './comments';
34
- export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
34
+ export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitAutoCaptionRenderJobParams, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
35
35
  export type { VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, VideoEditorImageSequenceSegment, VideoEditorVideoSequenceSegment, TimeValue, TimeMode, SegmentTimelinePosition, DeduplicationLevel, DeduplicationInput, ImageEditorElement, DimensionPresetKey, } from './render/types';
36
36
  export type { ImageEditorNodeConfig, ImageComposerNodeConfig, ImageComposerRenderInput } from './automations/nodes/image-composer';
37
37
  export { prepareImageComposerInput } from './automations/nodes/image-composer';
package/dist/render.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { ApiResponse } from './types';
2
2
  import type { VideoEditorNodeConfig, DeduplicationInput } from './render/types';
3
+ import type { CaptionWord, CaptionStyle } from './render/types/caption';
3
4
  import type { ImageEditorNodeConfig } from './automations/nodes/image-composer';
5
+ import type { CreateDmMessage } from './automations/nodes/create-dm';
4
6
  export interface RenderJobResponse {
5
7
  job_id: string;
6
8
  status: string;
@@ -60,12 +62,29 @@ export interface SubmitScreenshotAnimationRenderJobParams {
60
62
  /** Duration to hold at end after animation completes (ms) - default 500 */
61
63
  holdDurationMs?: number;
62
64
  }
63
- export interface IgDmMessage {
65
+ export interface SubmitAutoCaptionRenderJobParams {
66
+ /** Video source URL */
67
+ videoUrl: string;
68
+ /** Output width in pixels */
69
+ width: number;
70
+ /** Output height in pixels */
71
+ height: number;
72
+ /** Video duration in milliseconds */
73
+ durationMs: number;
74
+ /** Frames per second */
75
+ fps: number;
76
+ /** Caption words with timing from transcription */
77
+ captions: CaptionWord[];
78
+ /** Caption styling configuration */
79
+ style: CaptionStyle;
80
+ }
81
+ interface IgDmMessageInternal {
64
82
  text: string;
65
83
  sender: 'user' | 'recipient';
66
84
  isStoryReply?: boolean;
67
85
  groupWithPrevious?: boolean;
68
86
  }
87
+ export type IgDmMessage = IgDmMessageInternal;
69
88
  export interface SubmitInstagramDmRenderJobParams {
70
89
  /** Receiver's username (shown in header) */
71
90
  receiverUsername: string;
@@ -74,17 +93,18 @@ export interface SubmitInstagramDmRenderJobParams {
74
93
  /** Theme - light or dark mode */
75
94
  theme: 'light' | 'dark';
76
95
  /** Messages in the conversation */
77
- messages: IgDmMessage[];
78
- /** Story image URL for story reply messages */
79
- storyImageUrl?: string;
96
+ messages: CreateDmMessage[];
97
+ /** Image attachment URL (used for story reply) */
98
+ imageAttachmentUrl?: string;
80
99
  }
81
- export interface ImDmMessage {
100
+ interface ImDmMessageInternal {
82
101
  id: string;
83
102
  sender: 'user' | 'recipient';
84
103
  text: string;
85
104
  imageUrl?: string;
86
105
  groupWithPrevious?: boolean;
87
106
  }
107
+ export type ImDmMessage = ImDmMessageInternal;
88
108
  export interface SubmitIMessageDmRenderJobParams {
89
109
  /** Username displayed in header */
90
110
  username: string;
@@ -95,7 +115,9 @@ export interface SubmitIMessageDmRenderJobParams {
95
115
  /** Status bar time */
96
116
  time: string;
97
117
  /** Messages in the conversation */
98
- messages: ImDmMessage[];
118
+ messages: CreateDmMessage[];
119
+ /** Image attachment URL (used for sender images with hasImage flag) */
120
+ imageAttachmentUrl?: string;
99
121
  /** Sender bubble color (default blue) */
100
122
  senderBubbleColor?: string;
101
123
  /** Whether to show read receipt */
@@ -135,6 +157,11 @@ export declare class RenderClient {
135
157
  * Renders an iPhone screenshot animation video from a source image
136
158
  */
137
159
  submitScreenshotAnimationRenderJob(params: SubmitScreenshotAnimationRenderJobParams): Promise<ApiResponse<RenderJobResponse>>;
160
+ /**
161
+ * Submit an auto-caption render job to the Modal renderer
162
+ * Renders a video with captions overlaid
163
+ */
164
+ submitAutoCaptionRenderJob(params: SubmitAutoCaptionRenderJobParams): Promise<ApiResponse<RenderJobResponse>>;
138
165
  /**
139
166
  * Submit an Instagram DM render job to the Modal renderer
140
167
  * Renders a fake Instagram DM conversation image
@@ -146,3 +173,4 @@ export declare class RenderClient {
146
173
  */
147
174
  submitIMessageDmRenderJob(params: SubmitIMessageDmRenderJobParams): Promise<ApiResponse<RenderJobResponse>>;
148
175
  }
176
+ export {};
package/dist/render.js CHANGED
@@ -4,6 +4,56 @@ exports.RenderClient = void 0;
4
4
  // Modal renderer endpoints
5
5
  const RENDER_SUBMIT_URL = "https://aidangollan--ugcinc-render-renderer-submit-job.modal.run";
6
6
  const RENDER_STATUS_URL = "https://aidangollan--ugcinc-render-renderer-get-status.modal.run";
7
+ // =============================================================================
8
+ // DM Message Transformation Helpers
9
+ // =============================================================================
10
+ /**
11
+ * Auto-detect groupWithPrevious for messages based on consecutive same-sender
12
+ */
13
+ function addGroupWithPrevious(messages) {
14
+ return messages.map((msg, index) => {
15
+ if (index === 0) {
16
+ return { ...msg, groupWithPrevious: false };
17
+ }
18
+ const prevMsg = messages[index - 1];
19
+ const shouldGroup = prevMsg !== undefined && msg.sender === prevMsg.sender;
20
+ return { ...msg, groupWithPrevious: shouldGroup };
21
+ });
22
+ }
23
+ /**
24
+ * Generate unique message IDs for iMessage messages
25
+ */
26
+ function generateMessageId(index) {
27
+ return `msg-${index}-${Date.now()}`;
28
+ }
29
+ /**
30
+ * Transform CreateDmMessage[] to IgDmMessageInternal[] for Instagram DM
31
+ */
32
+ function transformToInstagramMessages(messages, imageAttachmentUrl) {
33
+ const processedMessages = addGroupWithPrevious(messages);
34
+ return processedMessages.map((msg) => ({
35
+ text: msg.text,
36
+ sender: msg.sender,
37
+ isStoryReply: msg.hasImage && imageAttachmentUrl ? true : false,
38
+ groupWithPrevious: msg.groupWithPrevious,
39
+ }));
40
+ }
41
+ /**
42
+ * Transform CreateDmMessage[] to ImDmMessageInternal[] for iMessage DM
43
+ */
44
+ function transformToIMessageMessages(messages, imageAttachmentUrl) {
45
+ const processedMessages = addGroupWithPrevious(messages);
46
+ return processedMessages.map((msg, index) => ({
47
+ id: generateMessageId(index),
48
+ sender: msg.sender,
49
+ text: msg.text,
50
+ imageUrl: msg.hasImage && msg.sender === 'user' ? imageAttachmentUrl : undefined,
51
+ groupWithPrevious: msg.groupWithPrevious,
52
+ }));
53
+ }
54
+ // =============================================================================
55
+ // Render Client
56
+ // =============================================================================
7
57
  /**
8
58
  * Client for rendering operations
9
59
  * Note: This calls Modal endpoints directly, not the UGC Inc API
@@ -305,12 +355,78 @@ class RenderClient {
305
355
  };
306
356
  }
307
357
  }
358
+ /**
359
+ * Submit an auto-caption render job to the Modal renderer
360
+ * Renders a video with captions overlaid
361
+ */
362
+ async submitAutoCaptionRenderJob(params) {
363
+ try {
364
+ const response = await fetch(RENDER_SUBMIT_URL, {
365
+ method: 'POST',
366
+ headers: {
367
+ 'Content-Type': 'application/json',
368
+ },
369
+ body: JSON.stringify({
370
+ config: {
371
+ _compositionType: 'auto-caption',
372
+ videoUrl: params.videoUrl,
373
+ width: params.width,
374
+ height: params.height,
375
+ durationMs: params.durationMs,
376
+ fps: params.fps,
377
+ captions: params.captions,
378
+ style: params.style,
379
+ },
380
+ output_type: 'video',
381
+ video_codec: 'h264',
382
+ })
383
+ });
384
+ const text = await response.text();
385
+ let data;
386
+ try {
387
+ data = JSON.parse(text);
388
+ }
389
+ catch (jsonError) {
390
+ console.error('[Render] JSON parse error:', text.substring(0, 200));
391
+ return {
392
+ ok: false,
393
+ code: response.status || 500,
394
+ message: `Modal endpoint error: ${text.substring(0, 100)}`,
395
+ };
396
+ }
397
+ if (data.status === 'error' || !response.ok) {
398
+ return {
399
+ ok: false,
400
+ code: response.status,
401
+ message: data.error ?? data.message ?? 'Failed to submit auto-caption job',
402
+ };
403
+ }
404
+ return {
405
+ ok: true,
406
+ code: 200,
407
+ message: "Auto-caption job submitted",
408
+ data,
409
+ };
410
+ }
411
+ catch (error) {
412
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
413
+ console.error('[Render] Submit auto-caption error:', error);
414
+ return {
415
+ ok: false,
416
+ code: 500,
417
+ message: `Failed to submit auto-caption job: ${errorMessage}`,
418
+ };
419
+ }
420
+ }
308
421
  /**
309
422
  * Submit an Instagram DM render job to the Modal renderer
310
423
  * Renders a fake Instagram DM conversation image
311
424
  */
312
425
  async submitInstagramDmRenderJob(params) {
313
426
  try {
427
+ // Transform CreateDmMessage[] to internal format
428
+ const transformedMessages = transformToInstagramMessages(params.messages, params.imageAttachmentUrl);
429
+ const hasStoryReply = params.messages.some(msg => msg.hasImage);
314
430
  const response = await fetch(RENDER_SUBMIT_URL, {
315
431
  method: 'POST',
316
432
  headers: {
@@ -323,8 +439,8 @@ class RenderClient {
323
439
  receiverUsername: params.receiverUsername,
324
440
  receiverProfilePicUrl: params.receiverProfilePicUrl,
325
441
  theme: params.theme,
326
- messages: params.messages,
327
- storyImageUrl: params.storyImageUrl,
442
+ messages: transformedMessages,
443
+ storyImageUrl: hasStoryReply ? params.imageAttachmentUrl : undefined,
328
444
  },
329
445
  },
330
446
  output_type: 'image',
@@ -374,6 +490,8 @@ class RenderClient {
374
490
  */
375
491
  async submitIMessageDmRenderJob(params) {
376
492
  try {
493
+ // Transform CreateDmMessage[] to internal format
494
+ const transformedMessages = transformToIMessageMessages(params.messages, params.imageAttachmentUrl);
377
495
  const response = await fetch(RENDER_SUBMIT_URL, {
378
496
  method: 'POST',
379
497
  headers: {
@@ -387,7 +505,7 @@ class RenderClient {
387
505
  profilePicUrl: params.profilePicUrl,
388
506
  theme: params.theme,
389
507
  time: params.time,
390
- messages: params.messages,
508
+ messages: transformedMessages,
391
509
  senderBubbleColor: params.senderBubbleColor,
392
510
  showReadReceipt: params.showReadReceipt,
393
511
  readReceiptText: params.readReceiptText,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc",
3
- "version": "4.1.46",
3
+ "version": "4.1.49",
4
4
  "description": "TypeScript/JavaScript client for the UGC Inc API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",