ugcinc 4.16.2 → 4.18.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.
- package/README.md +75 -0
- package/dist/automations/index.d.ts +1 -1
- package/dist/automations/nodes/index.d.ts +27 -0
- package/dist/automations/nodes/index.js +2 -0
- package/dist/automations/nodes/remotion-composition.d.ts +42 -0
- package/dist/automations/nodes/remotion-composition.js +32 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +10 -3
- package/dist/post-failure.d.ts +10 -0
- package/dist/post-failure.js +2 -0
- package/dist/posts.d.ts +4 -0
- package/dist/render/compositions/IMessageDmComposition/types.d.ts +4 -4
- package/dist/render/types/remotion-composition.d.ts +120 -0
- package/dist/render/types/remotion-composition.js +41 -0
- package/dist/render.d.ts +3 -0
- package/dist/render.js +22 -0
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,6 +74,20 @@ if (posts.ok) {
|
|
|
74
74
|
}
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
## Posting failure quick reference
|
|
78
|
+
|
|
79
|
+
`posts.getStatus()` returns `failure`; both `getPosts()` and `getPostsPage()` include it on each post. It is `null` when there is no current posting issue. A successful lookup still returns HTTP 200 even if the post failed.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const result = await client.posts.getStatus({ postId: "post_123" });
|
|
83
|
+
if (result.ok && result.data.failure) {
|
|
84
|
+
const { code, message, recovery, next_action } = result.data.failure;
|
|
85
|
+
console.log(code, message, recovery, next_action);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
See the posting failure reference below for recovery states and messages.
|
|
90
|
+
|
|
77
91
|
## Pagination
|
|
78
92
|
|
|
79
93
|
`accounts.getAccounts()` and `posts.getPosts()` support keyset pagination via `limit`/`cursor`.
|
|
@@ -205,3 +219,64 @@ For the full endpoint reference, all method signatures, data structures, and wor
|
|
|
205
219
|
## License
|
|
206
220
|
|
|
207
221
|
MIT
|
|
222
|
+
|
|
223
|
+
## Posting failure reference
|
|
224
|
+
|
|
225
|
+
The same `failure` object is returned by status and list responses. It contains a stable `code`, a fixed `message`, a `recovery` state, and `next_action`.
|
|
226
|
+
|
|
227
|
+
| Recovery | Meaning |
|
|
228
|
+
|---|---|
|
|
229
|
+
| `retry_pending` | The existing post is waiting for another attempt; no execution time is guaranteed. |
|
|
230
|
+
| `waiting` | The existing post is paused until a publishing issue is resolved. |
|
|
231
|
+
| `verifying_publication` | Publication is being checked before another attempt is allowed. |
|
|
232
|
+
| `stopped` | No automatic recovery is indicated. Follow `next_action`. |
|
|
233
|
+
|
|
234
|
+
`next_action` is `wait`, `change_audio`, `change_audio_or_contact_support`, or `contact_support`. When it is `wait`, do not submit another copy. Account and publishing operations are handled by the service; these messages never ask customers to manage them.
|
|
235
|
+
|
|
236
|
+
| Code | Message |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `AUDIO_UNAVAILABLE` | The selected sound is unavailable. Choose another sound and retry. |
|
|
239
|
+
| `BACKUP_AUDIO_RETRY_PENDING` | The selected sound was unavailable. Your post is waiting to be retried with its backup sound. |
|
|
240
|
+
| `AUDIO_RETRY_PENDING` | The selected sound could not be loaded. Your post is waiting to be retried. |
|
|
241
|
+
| `AUDIO_PREPARATION_FAILED` | The selected sound could not be prepared for this post. Choose another sound or contact support before retrying. |
|
|
242
|
+
| `PUBLISHING_RETRY_PENDING` | Publishing was temporarily interrupted. Your post is waiting to be retried. No action is needed. |
|
|
243
|
+
| `PUBLISHING_BLOCKED` | A publishing issue prevented this post from proceeding. Contact support for help with this post. |
|
|
244
|
+
| `POST_PROCESSING_FAILED` | A processing error prevented this posting attempt from completing. Contact support before retrying. |
|
|
245
|
+
| `PUBLICATION_CHECK_IN_PROGRESS` | We’re checking whether your post published. Please wait before submitting it again to avoid a duplicate. |
|
|
246
|
+
| `PUBLICATION_UNCONFIRMED` | We couldn’t confirm whether your post published. Contact support before submitting it again to avoid a duplicate. |
|
|
247
|
+
| `POST_RETRY_PENDING` | The previous posting attempt did not complete. Your post is waiting to be retried. No action is needed. |
|
|
248
|
+
| `POST_FAILED` | The posting attempt failed, but we couldn’t determine the cause. Contact support before submitting it again. |
|
|
249
|
+
|
|
250
|
+
### Render a supplied Remotion composition
|
|
251
|
+
|
|
252
|
+
`remotion-composition` accepts a TSX module whose default export is a React
|
|
253
|
+
component. UGC supplies registration, bundling and video rendering. Static imports
|
|
254
|
+
may use `react`, `remotion`, `ugcinc/render`, `ugcinc/render/utils`, and
|
|
255
|
+
`ugcinc/render/types`. Dependencies and UGC components come from the render runtime;
|
|
256
|
+
local-file imports, dynamic imports, npm installation and build scripts are not accepted.
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
await client.automations.runNode({
|
|
260
|
+
nodeType: 'remotion-composition',
|
|
261
|
+
config: {
|
|
262
|
+
source: `import React from 'react';
|
|
263
|
+
import {AbsoluteFill} from 'remotion';
|
|
264
|
+
export default function Video({title}) {
|
|
265
|
+
return <AbsoluteFill style={{background: 'white', fontSize: 80}}>{title}</AbsoluteFill>;
|
|
266
|
+
}`,
|
|
267
|
+
width: 1080, height: 1920, fps: 30, durationInFrames: 150,
|
|
268
|
+
inputProps: {title: 'A new video'},
|
|
269
|
+
},
|
|
270
|
+
waitForCompletion: true,
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
In a workflow, add `inputs: [{id: 'title', type: 'text', isArray: false,
|
|
275
|
+
required: true}]` to create a connected prop. Connected values override
|
|
276
|
+
`inputProps` defaults. Media inputs retain their `{url}` shape. The `output` port
|
|
277
|
+
is a video suitable for Save to Media or Pass Through. Rendering errors identify
|
|
278
|
+
invalid source, unsupported imports or missing inputs. Use normal automation run
|
|
279
|
+
status/logs to inspect failures and the returned video for preview.
|
|
280
|
+
|
|
281
|
+
Server integrations can also call `submitRemotionCompositionRenderJob` and
|
|
282
|
+
`getRenderJobStatus` with the configured render-worker origin.
|
|
@@ -75,7 +75,7 @@ export declare class AutomationsClient extends BaseClient {
|
|
|
75
75
|
* Run a single automation node by compiling it to a minimal inline workflow.
|
|
76
76
|
*/
|
|
77
77
|
runNode(params: {
|
|
78
|
-
nodeType: 'scene-split' | 'generate-image' | 'generate-video';
|
|
78
|
+
nodeType: 'scene-split' | 'generate-image' | 'generate-video' | 'remotion-composition';
|
|
79
79
|
inputs?: Record<string, PortValue>;
|
|
80
80
|
config?: Record<string, unknown>;
|
|
81
81
|
waitForCompletion?: boolean;
|
|
@@ -332,6 +332,33 @@ export declare const nodeDefinitions: {
|
|
|
332
332
|
__TInputs: import("./screenshot-animation").ScreenshotAnimationNodeInputs;
|
|
333
333
|
__TOutputs: import("./screenshot-animation").ScreenshotAnimationNodeOutputs;
|
|
334
334
|
};
|
|
335
|
+
readonly 'remotion-composition': NodeDefinition<"remotion-composition", "generator", {
|
|
336
|
+
source: string;
|
|
337
|
+
outputMode: "per-input" | "single";
|
|
338
|
+
selectionMode: null;
|
|
339
|
+
inputs: {
|
|
340
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
341
|
+
id: string;
|
|
342
|
+
isArray: boolean;
|
|
343
|
+
required: boolean;
|
|
344
|
+
}[];
|
|
345
|
+
width: number;
|
|
346
|
+
height: number;
|
|
347
|
+
fps: number;
|
|
348
|
+
durationInFrames: number;
|
|
349
|
+
inputProps: Record<string, unknown>;
|
|
350
|
+
}, {
|
|
351
|
+
[x: string]: import("../types").PortValue | import("../types").PortValue[];
|
|
352
|
+
}, {
|
|
353
|
+
output: import("../types").VideoValue;
|
|
354
|
+
}, false> & {
|
|
355
|
+
__TInputs: {
|
|
356
|
+
[x: string]: import("../types").PortValue | import("../types").PortValue[];
|
|
357
|
+
};
|
|
358
|
+
__TOutputs: {
|
|
359
|
+
output: import("../types").VideoValue;
|
|
360
|
+
};
|
|
361
|
+
};
|
|
335
362
|
readonly 'social-audio': NodeDefinition<"social-audio", "source", {
|
|
336
363
|
audioPool: import("../types").SocialAudioValue[];
|
|
337
364
|
selectedMediaIds: string[];
|
|
@@ -38,6 +38,7 @@ const random_route_1 = __importDefault(require("./random-route"));
|
|
|
38
38
|
const save_to_media_1 = __importDefault(require("./save-to-media"));
|
|
39
39
|
const scene_split_1 = __importDefault(require("./scene-split"));
|
|
40
40
|
const screenshot_animation_1 = __importDefault(require("./screenshot-animation"));
|
|
41
|
+
const remotion_composition_1 = __importDefault(require("./remotion-composition"));
|
|
41
42
|
const social_audio_1 = __importDefault(require("./social-audio"));
|
|
42
43
|
const text_1 = __importDefault(require("./text"));
|
|
43
44
|
const transcript_1 = __importDefault(require("./transcript"));
|
|
@@ -79,6 +80,7 @@ exports.nodeDefinitions = {
|
|
|
79
80
|
'save-to-media': save_to_media_1.default,
|
|
80
81
|
'scene-split': scene_split_1.default,
|
|
81
82
|
'screenshot-animation': screenshot_animation_1.default,
|
|
83
|
+
'remotion-composition': remotion_composition_1.default,
|
|
82
84
|
'social-audio': social_audio_1.default,
|
|
83
85
|
'text': text_1.default,
|
|
84
86
|
'transcript': transcript_1.default,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { PortValue, VideoValue } from '../types';
|
|
2
|
+
type Inputs = Record<string, PortValue | PortValue[]>;
|
|
3
|
+
type Outputs = {
|
|
4
|
+
output: VideoValue;
|
|
5
|
+
};
|
|
6
|
+
declare const defaults: {
|
|
7
|
+
source: string;
|
|
8
|
+
outputMode: "per-input" | "single";
|
|
9
|
+
selectionMode: null;
|
|
10
|
+
inputs: {
|
|
11
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
12
|
+
id: string;
|
|
13
|
+
isArray: boolean;
|
|
14
|
+
required: boolean;
|
|
15
|
+
}[];
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
fps: number;
|
|
19
|
+
durationInFrames: number;
|
|
20
|
+
inputProps: Record<string, unknown>;
|
|
21
|
+
};
|
|
22
|
+
declare const _default: import("./types").NodeDefinition<"remotion-composition", "generator", {
|
|
23
|
+
source: string;
|
|
24
|
+
outputMode: "per-input" | "single";
|
|
25
|
+
selectionMode: null;
|
|
26
|
+
inputs: {
|
|
27
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
28
|
+
id: string;
|
|
29
|
+
isArray: boolean;
|
|
30
|
+
required: boolean;
|
|
31
|
+
}[];
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
fps: number;
|
|
35
|
+
durationInFrames: number;
|
|
36
|
+
inputProps: Record<string, unknown>;
|
|
37
|
+
}, Inputs, Outputs, false> & {
|
|
38
|
+
__TInputs: Inputs;
|
|
39
|
+
__TOutputs: Outputs;
|
|
40
|
+
};
|
|
41
|
+
export default _default;
|
|
42
|
+
export type RemotionCompositionNodeConfig = typeof defaults;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const remotion_composition_1 = require("../../render/types/remotion-composition");
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const defaults = remotion_composition_1.remotionCompositionNodeSchema.parse({
|
|
6
|
+
source: `import React from 'react';
|
|
7
|
+
import {AbsoluteFill} from 'remotion';
|
|
8
|
+
|
|
9
|
+
export default function Video({title}: {title: string}) {
|
|
10
|
+
return <AbsoluteFill style={{background: '#fff', justifyContent: 'center', alignItems: 'center', fontSize: 64}}>{title}</AbsoluteFill>;
|
|
11
|
+
}`,
|
|
12
|
+
width: 1080, height: 1920, fps: 30, durationInFrames: 150,
|
|
13
|
+
inputProps: { title: 'Your video' }, inputs: [], outputMode: 'per-input', selectionMode: null,
|
|
14
|
+
});
|
|
15
|
+
const definition = (0, types_1.defineNode)({
|
|
16
|
+
nodeId: 'remotion-composition', label: 'Remotion Composition',
|
|
17
|
+
description: 'Render a React/TSX composition with UGC components',
|
|
18
|
+
guide: 'Supply a TSX module with a default-exported React component. UGC registers and bundles it. Import react, remotion or ugcinc/render (including its utils/types subpaths). Configure dimensions, fps, frame count and default inputProps. Add typed input ports whose IDs match component props; connected values override defaults. Media props retain their {url} shape. Source is browser code: no local files, npm installs, require or dynamic imports. Output is a rendered video; use Save to Media or Pass Through. Run preview uses the same renderer as the final output.',
|
|
19
|
+
type: 'generator', category: 'Generation', outputModes: ['per-input', 'single'], selectionModes: null,
|
|
20
|
+
defaults,
|
|
21
|
+
computePorts: ({ config }) => ({ inputs: config.inputs,
|
|
22
|
+
outputs: [{ id: 'output', type: 'video', isArray: false, required: true }] }),
|
|
23
|
+
generatePreview: (_config, _ctx, cached) => (0, types_1.preview)({ output: cached?.output ?? null }),
|
|
24
|
+
validate: config => {
|
|
25
|
+
const result = remotion_composition_1.remotionCompositionNodeSchema.safeParse(config);
|
|
26
|
+
return result.success ? [] : result.error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
// Runtime markers preserve the registry's typed input/output inference without casts.
|
|
30
|
+
const inputTypes = {};
|
|
31
|
+
const outputTypes = { output: { url: '' } };
|
|
32
|
+
exports.default = Object.assign(definition, { __TInputs: inputTypes, __TOutputs: outputTypes });
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,10 @@ export { AutomationsClient } from './automations';
|
|
|
13
13
|
export { MediaClient } from './media';
|
|
14
14
|
export { CommentsClient } from './comments';
|
|
15
15
|
export { BillingClient } from './billing';
|
|
16
|
-
export { submitImageRenderJob, submitVideoRenderJob, getRenderJobStatus, submitDeduplicationJob, submitSceneSplitJob, submitScreenshotAnimationRenderJob, submitAutoCaptionRenderJob, submitInstagramDmRenderJob, submitIMessageDmRenderJob, } from './render';
|
|
16
|
+
export { submitImageRenderJob, submitVideoRenderJob, getRenderJobStatus, submitDeduplicationJob, submitSceneSplitJob, submitScreenshotAnimationRenderJob, submitRemotionCompositionRenderJob, submitAutoCaptionRenderJob, submitInstagramDmRenderJob, submitIMessageDmRenderJob, } from './render';
|
|
17
|
+
export { remotionCompositionSchema, remotionCompositionNodeSchema, remotionCompositionPortSchema, REMOTION_COMPOSITION_IMPORTS, parseRemotionPropsJson } from './render/types/remotion-composition';
|
|
18
|
+
export type { RemotionCompositionInput } from './render/types/remotion-composition';
|
|
19
|
+
export type { RemotionCompositionNodeConfig } from './automations/nodes/remotion-composition';
|
|
17
20
|
export { areTypesCompatible, computePortsForNode, computePortsWithPreviews, computeAllNodePorts, computeAllNodePortsWithPreviews, getInputPreviewValue, getAllNodes, getNodeByType, getOutputSchema, createNode, deriveConnections, addConnection, removeConnection, removeNodeConnections, cleanupStaleConnections, getConnectedSource, getForEachContext, checkCrossContextViolation, getDownstreamNodes, getNodesDownstreamOfSet, getCapturedNodes, validateWorkflow, getErrorNodeIds, getPortErrorsForNode, hasMissingTriggerError, hasMissingTerminalError, getWorkflowOutputSchema, resolveNodePreview, computeAllNodePreviews, computePreviewMap, updatePreviewMapForConnection, removePreviewForConnection, getPreviewValue, shuffleNodePreview, type PreviewMap, type NodePreviewOutputs, type Connection, generateNodeName, extractWorkflowConfig, type WorkflowTemplateData, } from './automations/graph-controller';
|
|
18
21
|
export { nodeDefinitions, internalNodeTypes, isAsyncExecutor, formatPortType, isPortType } from './automations/types';
|
|
19
22
|
export { getNodeDefinition, getAllNodeDefinitions, getFlowControlNodeTypes, getCapturedSourceNodeTypes } from './automations/nodes';
|
|
@@ -81,3 +84,4 @@ export type { NodeDefinition, NodeType, UserCreatableNodeType, NodeConfig, Workf
|
|
|
81
84
|
export type { SelectionMode, ExhaustionBehavior, SelectionConfig, SelectionState, OutputMode, NodeCategory, TriggerIterationMode, IterationExhaustionBehavior, CollectionSelectionMode, TriggerCollectionConfig, MediaItemType, MediaNodeSelectionType, ResolvedPreview, PreviewSelectionState, PreviewContext, NullableOutputs, } from './automations/nodes/types';
|
|
82
85
|
export type { SuccessResponse, ErrorResponse, ApiResponse, } from './types';
|
|
83
86
|
export type { CropBoundary, CropAxisConfig, DynamicCropConfig, BorderRadiusConfig, VerticalAnchor, HorizontalAnchor, HorizontalSelfAnchor, VerticalSelfAnchor, RelativePositionConfigX, RelativePositionConfigY, } from './render/types';
|
|
87
|
+
export type { PublicPostFailureCode, PublicPostRecovery, PublicPostNextAction, PublicPostFailure } from './post-failure';
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* Official TypeScript/JavaScript client for the UGC Inc API
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.prepareVideoComposerInput = exports.formatDateTag = exports.outputFieldsToZod = exports.outputFieldToZod = exports.LLMProviders = exports.applyLogicOperator = void 0;
|
|
8
|
+
exports.hasMissingTriggerError = exports.getPortErrorsForNode = exports.getErrorNodeIds = exports.validateWorkflow = exports.getCapturedNodes = exports.getNodesDownstreamOfSet = exports.getDownstreamNodes = 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.parseRemotionPropsJson = exports.REMOTION_COMPOSITION_IMPORTS = exports.remotionCompositionPortSchema = exports.remotionCompositionNodeSchema = exports.remotionCompositionSchema = exports.submitIMessageDmRenderJob = exports.submitInstagramDmRenderJob = exports.submitAutoCaptionRenderJob = exports.submitRemotionCompositionRenderJob = exports.submitScreenshotAnimationRenderJob = exports.submitSceneSplitJob = exports.submitDeduplicationJob = exports.getRenderJobStatus = exports.submitVideoRenderJob = exports.submitImageRenderJob = exports.BillingClient = exports.CommentsClient = exports.MediaClient = exports.AutomationsClient = exports.OrganizationClient = exports.StatsClient = exports.PostsClient = exports.TasksClient = exports.AccountsClient = exports.UGCClient = void 0;
|
|
9
|
+
exports.parseOpenAPIOutputPath = exports.parseOpenAPIInputs = exports.mapOpenAPIType = exports.nodeConfigToCaptionStyle = exports.HttpMethods = exports.prepareImageComposerInput = exports.substituteVariables = 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.getAvailableInputModes = exports.hasReferenceVariant = exports.getReferenceModelId = exports.hasFirstLastFrameVariant = exports.getFirstLastFrameModelId = exports.hasImageToVideoVariant = exports.getImageToVideoModelId = exports.isImageToVideoModel = exports.IMAGE_ASPECT_RATIOS = exports.ALL_IMAGE_MODELS = exports.getEditModelId = exports.isEditModel = exports.getCapturedSourceNodeTypes = exports.getFlowControlNodeTypes = exports.getAllNodeDefinitions = exports.getNodeDefinition = exports.isPortType = exports.formatPortType = exports.isAsyncExecutor = exports.internalNodeTypes = exports.nodeDefinitions = exports.extractWorkflowConfig = exports.generateNodeName = exports.shuffleNodePreview = exports.getPreviewValue = exports.removePreviewForConnection = exports.updatePreviewMapForConnection = exports.computePreviewMap = exports.computeAllNodePreviews = exports.resolveNodePreview = exports.getWorkflowOutputSchema = exports.hasMissingTerminalError = void 0;
|
|
10
|
+
exports.prepareVideoComposerInput = exports.formatDateTag = exports.outputFieldsToZod = exports.outputFieldToZod = exports.LLMProviders = exports.applyLogicOperator = exports.IfLogicOperators = exports.resolvePath = exports.indexExpressionToString = exports.indexExpressionToIndexes = exports.resolveUnknownPath = exports.getOutputTypeFromCategory = void 0;
|
|
11
11
|
// =============================================================================
|
|
12
12
|
// Client Exports
|
|
13
13
|
// =============================================================================
|
|
@@ -39,9 +39,16 @@ Object.defineProperty(exports, "getRenderJobStatus", { enumerable: true, get: fu
|
|
|
39
39
|
Object.defineProperty(exports, "submitDeduplicationJob", { enumerable: true, get: function () { return render_1.submitDeduplicationJob; } });
|
|
40
40
|
Object.defineProperty(exports, "submitSceneSplitJob", { enumerable: true, get: function () { return render_1.submitSceneSplitJob; } });
|
|
41
41
|
Object.defineProperty(exports, "submitScreenshotAnimationRenderJob", { enumerable: true, get: function () { return render_1.submitScreenshotAnimationRenderJob; } });
|
|
42
|
+
Object.defineProperty(exports, "submitRemotionCompositionRenderJob", { enumerable: true, get: function () { return render_1.submitRemotionCompositionRenderJob; } });
|
|
42
43
|
Object.defineProperty(exports, "submitAutoCaptionRenderJob", { enumerable: true, get: function () { return render_1.submitAutoCaptionRenderJob; } });
|
|
43
44
|
Object.defineProperty(exports, "submitInstagramDmRenderJob", { enumerable: true, get: function () { return render_1.submitInstagramDmRenderJob; } });
|
|
44
45
|
Object.defineProperty(exports, "submitIMessageDmRenderJob", { enumerable: true, get: function () { return render_1.submitIMessageDmRenderJob; } });
|
|
46
|
+
var remotion_composition_1 = require("./render/types/remotion-composition");
|
|
47
|
+
Object.defineProperty(exports, "remotionCompositionSchema", { enumerable: true, get: function () { return remotion_composition_1.remotionCompositionSchema; } });
|
|
48
|
+
Object.defineProperty(exports, "remotionCompositionNodeSchema", { enumerable: true, get: function () { return remotion_composition_1.remotionCompositionNodeSchema; } });
|
|
49
|
+
Object.defineProperty(exports, "remotionCompositionPortSchema", { enumerable: true, get: function () { return remotion_composition_1.remotionCompositionPortSchema; } });
|
|
50
|
+
Object.defineProperty(exports, "REMOTION_COMPOSITION_IMPORTS", { enumerable: true, get: function () { return remotion_composition_1.REMOTION_COMPOSITION_IMPORTS; } });
|
|
51
|
+
Object.defineProperty(exports, "parseRemotionPropsJson", { enumerable: true, get: function () { return remotion_composition_1.parseRemotionPropsJson; } });
|
|
45
52
|
// =============================================================================
|
|
46
53
|
// Graph Controller Exports
|
|
47
54
|
// =============================================================================
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Customer-facing posting explanations. No operational diagnostics are exposed. */
|
|
2
|
+
export type PublicPostFailureCode = 'AUDIO_UNAVAILABLE' | 'BACKUP_AUDIO_RETRY_PENDING' | 'AUDIO_RETRY_PENDING' | 'AUDIO_PREPARATION_FAILED' | 'PUBLISHING_RETRY_PENDING' | 'PUBLISHING_BLOCKED' | 'POST_PROCESSING_FAILED' | 'PUBLICATION_CHECK_IN_PROGRESS' | 'PUBLICATION_UNCONFIRMED' | 'POST_RETRY_PENDING' | 'POST_FAILED';
|
|
3
|
+
export type PublicPostRecovery = 'retry_pending' | 'waiting' | 'verifying_publication' | 'stopped';
|
|
4
|
+
export type PublicPostNextAction = 'wait' | 'change_audio' | 'change_audio_or_contact_support' | 'contact_support';
|
|
5
|
+
export interface PublicPostFailure {
|
|
6
|
+
code: PublicPostFailureCode;
|
|
7
|
+
message: string;
|
|
8
|
+
recovery: PublicPostRecovery;
|
|
9
|
+
next_action: PublicPostNextAction;
|
|
10
|
+
}
|
package/dist/posts.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseClient } from './base';
|
|
2
2
|
import type { ApiResponse } from './types';
|
|
3
|
+
import type { PublicPostFailure } from './post-failure';
|
|
3
4
|
/**
|
|
4
5
|
* Why a post failed, as a stable, client-safe category.
|
|
5
6
|
*
|
|
@@ -31,6 +32,8 @@ export interface CaptionOverlay {
|
|
|
31
32
|
fontSize: number;
|
|
32
33
|
}
|
|
33
34
|
export interface Post {
|
|
35
|
+
/** Present in list responses; null when there is no current posting issue. */
|
|
36
|
+
failure?: PublicPostFailure | null;
|
|
34
37
|
id: string;
|
|
35
38
|
account_id: string | null;
|
|
36
39
|
type: PostType;
|
|
@@ -251,6 +254,7 @@ export declare class PostsClient extends BaseClient {
|
|
|
251
254
|
postUrl?: string;
|
|
252
255
|
/** Set when status is "failed"; null otherwise. */
|
|
253
256
|
fail_category: PostFailCategory | null;
|
|
257
|
+
failure: PublicPostFailure | null;
|
|
254
258
|
}>>;
|
|
255
259
|
/**
|
|
256
260
|
* Create a video post
|
|
@@ -385,14 +385,14 @@ export declare const iMessageDmPropsSchema: z.ZodObject<{
|
|
|
385
385
|
groupWithPrevious: z.ZodOptional<z.ZodBoolean>;
|
|
386
386
|
}, "strip", z.ZodTypeAny, {
|
|
387
387
|
text: string;
|
|
388
|
-
sender: "user" | "recipient";
|
|
389
388
|
id: string;
|
|
389
|
+
sender: "user" | "recipient";
|
|
390
390
|
imageUrl?: string | undefined;
|
|
391
391
|
groupWithPrevious?: boolean | undefined;
|
|
392
392
|
}, {
|
|
393
393
|
text: string;
|
|
394
|
-
sender: "user" | "recipient";
|
|
395
394
|
id: string;
|
|
395
|
+
sender: "user" | "recipient";
|
|
396
396
|
imageUrl?: string | undefined;
|
|
397
397
|
groupWithPrevious?: boolean | undefined;
|
|
398
398
|
}>, "many">>;
|
|
@@ -406,8 +406,8 @@ export declare const iMessageDmPropsSchema: z.ZodObject<{
|
|
|
406
406
|
profilePicUrl?: string | undefined;
|
|
407
407
|
messages?: {
|
|
408
408
|
text: string;
|
|
409
|
-
sender: "user" | "recipient";
|
|
410
409
|
id: string;
|
|
410
|
+
sender: "user" | "recipient";
|
|
411
411
|
imageUrl?: string | undefined;
|
|
412
412
|
groupWithPrevious?: boolean | undefined;
|
|
413
413
|
}[] | undefined;
|
|
@@ -589,8 +589,8 @@ export declare const iMessageDmPropsSchema: z.ZodObject<{
|
|
|
589
589
|
profilePicUrl?: string | undefined;
|
|
590
590
|
messages?: {
|
|
591
591
|
text: string;
|
|
592
|
-
sender: "user" | "recipient";
|
|
593
592
|
id: string;
|
|
593
|
+
sender: "user" | "recipient";
|
|
594
594
|
imageUrl?: string | undefined;
|
|
595
595
|
groupWithPrevious?: boolean | undefined;
|
|
596
596
|
}[] | undefined;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** A React component module. UGC supplies the root and bundled dependencies. */
|
|
3
|
+
export declare const remotionCompositionSchema: z.ZodObject<{
|
|
4
|
+
source: z.ZodString;
|
|
5
|
+
width: z.ZodNumber;
|
|
6
|
+
height: z.ZodNumber;
|
|
7
|
+
fps: z.ZodNumber;
|
|
8
|
+
durationInFrames: z.ZodNumber;
|
|
9
|
+
inputProps: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
10
|
+
}, "strict", z.ZodTypeAny, {
|
|
11
|
+
source: string;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
fps: number;
|
|
15
|
+
durationInFrames: number;
|
|
16
|
+
inputProps: Record<string, unknown>;
|
|
17
|
+
}, {
|
|
18
|
+
source: string;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
fps: number;
|
|
22
|
+
durationInFrames: number;
|
|
23
|
+
inputProps: Record<string, unknown>;
|
|
24
|
+
}>;
|
|
25
|
+
export type RemotionCompositionInput = z.infer<typeof remotionCompositionSchema>;
|
|
26
|
+
export declare const remotionCompositionPortSchema: z.ZodObject<{
|
|
27
|
+
id: z.ZodEffects<z.ZodString, string, string>;
|
|
28
|
+
type: z.ZodEnum<["text", "number", "boolean", "image", "video", "audio", "object"]>;
|
|
29
|
+
isArray: z.ZodBoolean;
|
|
30
|
+
required: z.ZodBoolean;
|
|
31
|
+
}, "strict", z.ZodTypeAny, {
|
|
32
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
33
|
+
id: string;
|
|
34
|
+
isArray: boolean;
|
|
35
|
+
required: boolean;
|
|
36
|
+
}, {
|
|
37
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
38
|
+
id: string;
|
|
39
|
+
isArray: boolean;
|
|
40
|
+
required: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
export declare const remotionCompositionNodeSchema: z.ZodObject<{
|
|
43
|
+
source: z.ZodString;
|
|
44
|
+
width: z.ZodNumber;
|
|
45
|
+
height: z.ZodNumber;
|
|
46
|
+
fps: z.ZodNumber;
|
|
47
|
+
durationInFrames: z.ZodNumber;
|
|
48
|
+
inputProps: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
49
|
+
} & {
|
|
50
|
+
inputs: z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
51
|
+
id: z.ZodEffects<z.ZodString, string, string>;
|
|
52
|
+
type: z.ZodEnum<["text", "number", "boolean", "image", "video", "audio", "object"]>;
|
|
53
|
+
isArray: z.ZodBoolean;
|
|
54
|
+
required: z.ZodBoolean;
|
|
55
|
+
}, "strict", z.ZodTypeAny, {
|
|
56
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
57
|
+
id: string;
|
|
58
|
+
isArray: boolean;
|
|
59
|
+
required: boolean;
|
|
60
|
+
}, {
|
|
61
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
62
|
+
id: string;
|
|
63
|
+
isArray: boolean;
|
|
64
|
+
required: boolean;
|
|
65
|
+
}>, "many">, {
|
|
66
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
67
|
+
id: string;
|
|
68
|
+
isArray: boolean;
|
|
69
|
+
required: boolean;
|
|
70
|
+
}[], {
|
|
71
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
72
|
+
id: string;
|
|
73
|
+
isArray: boolean;
|
|
74
|
+
required: boolean;
|
|
75
|
+
}[]>;
|
|
76
|
+
outputMode: z.ZodEnum<["single", "per-input"]>;
|
|
77
|
+
selectionMode: z.ZodNull;
|
|
78
|
+
}, "strict", z.ZodTypeAny, {
|
|
79
|
+
source: string;
|
|
80
|
+
outputMode: "per-input" | "single";
|
|
81
|
+
selectionMode: null;
|
|
82
|
+
inputs: {
|
|
83
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
84
|
+
id: string;
|
|
85
|
+
isArray: boolean;
|
|
86
|
+
required: boolean;
|
|
87
|
+
}[];
|
|
88
|
+
width: number;
|
|
89
|
+
height: number;
|
|
90
|
+
fps: number;
|
|
91
|
+
durationInFrames: number;
|
|
92
|
+
inputProps: Record<string, unknown>;
|
|
93
|
+
}, {
|
|
94
|
+
source: string;
|
|
95
|
+
outputMode: "per-input" | "single";
|
|
96
|
+
selectionMode: null;
|
|
97
|
+
inputs: {
|
|
98
|
+
type: "number" | "boolean" | "object" | "video" | "audio" | "image" | "text";
|
|
99
|
+
id: string;
|
|
100
|
+
isArray: boolean;
|
|
101
|
+
required: boolean;
|
|
102
|
+
}[];
|
|
103
|
+
width: number;
|
|
104
|
+
height: number;
|
|
105
|
+
fps: number;
|
|
106
|
+
durationInFrames: number;
|
|
107
|
+
inputProps: Record<string, unknown>;
|
|
108
|
+
}>;
|
|
109
|
+
export declare const REMOTION_COMPOSITION_IMPORTS: string[];
|
|
110
|
+
export declare function parseRemotionPropsJson({ text }: {
|
|
111
|
+
text: string;
|
|
112
|
+
}): {
|
|
113
|
+
ok: false;
|
|
114
|
+
message: string;
|
|
115
|
+
value?: undefined;
|
|
116
|
+
} | {
|
|
117
|
+
ok: true;
|
|
118
|
+
value: Record<string, unknown>;
|
|
119
|
+
message?: undefined;
|
|
120
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REMOTION_COMPOSITION_IMPORTS = exports.remotionCompositionNodeSchema = exports.remotionCompositionPortSchema = exports.remotionCompositionSchema = void 0;
|
|
4
|
+
exports.parseRemotionPropsJson = parseRemotionPropsJson;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
/** A React component module. UGC supplies the root and bundled dependencies. */
|
|
7
|
+
exports.remotionCompositionSchema = zod_1.z.object({
|
|
8
|
+
source: zod_1.z.string().trim().min(1).max(200000),
|
|
9
|
+
width: zod_1.z.number().int().min(16).max(3840).multipleOf(2),
|
|
10
|
+
height: zod_1.z.number().int().min(16).max(3840).multipleOf(2),
|
|
11
|
+
fps: zod_1.z.number().int().min(1).max(60),
|
|
12
|
+
durationInFrames: zod_1.z.number().int().min(1).max(18000),
|
|
13
|
+
inputProps: zod_1.z.record(zod_1.z.unknown()),
|
|
14
|
+
}).strict();
|
|
15
|
+
exports.remotionCompositionPortSchema = zod_1.z.object({
|
|
16
|
+
id: zod_1.z.string().regex(/^[A-Za-z][A-Za-z0-9_]*$/, 'Use a simple prop name').refine(id => !['constructor', 'prototype', '__proto__'].includes(id), 'Reserved prop name'),
|
|
17
|
+
type: zod_1.z.enum(['text', 'number', 'boolean', 'image', 'video', 'audio', 'object']),
|
|
18
|
+
isArray: zod_1.z.boolean(),
|
|
19
|
+
required: zod_1.z.boolean(),
|
|
20
|
+
}).strict();
|
|
21
|
+
exports.remotionCompositionNodeSchema = exports.remotionCompositionSchema.extend({
|
|
22
|
+
inputs: zod_1.z.array(exports.remotionCompositionPortSchema).max(64).refine(ports => new Set(ports.map(port => port.id)).size === ports.length, 'Prop names must be unique'),
|
|
23
|
+
outputMode: zod_1.z.enum(['single', 'per-input']),
|
|
24
|
+
selectionMode: zod_1.z.null(),
|
|
25
|
+
});
|
|
26
|
+
exports.REMOTION_COMPOSITION_IMPORTS = [
|
|
27
|
+
'react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'remotion',
|
|
28
|
+
'ugcinc/render', 'ugcinc/render/utils', 'ugcinc/render/types',
|
|
29
|
+
];
|
|
30
|
+
function parseRemotionPropsJson({ text }) {
|
|
31
|
+
try {
|
|
32
|
+
const value = JSON.parse(text);
|
|
33
|
+
const parsed = zod_1.z.record(zod_1.z.unknown()).safeParse(value);
|
|
34
|
+
if (!parsed.success)
|
|
35
|
+
return { ok: false, message: 'Props must be a JSON object' };
|
|
36
|
+
return { ok: true, value: parsed.data };
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return { ok: false, message: 'Enter valid JSON' };
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/render.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ import type { VideoEditorNodeConfig, DeduplicationInput } from './render/types';
|
|
|
12
12
|
import type { CaptionWord, CaptionStyle } from './render/types/caption';
|
|
13
13
|
import type { ImageEditorNodeConfig } from './automations/nodes/image-composer';
|
|
14
14
|
import type { CreateDmMessage } from './automations/nodes/create-dm';
|
|
15
|
+
import { type RemotionCompositionInput } from './render/types/remotion-composition';
|
|
16
|
+
/** Submit TSX source and props; UGC owns registration and bundling. */
|
|
17
|
+
export declare function submitRemotionCompositionRenderJob(params: RemotionCompositionInput): Promise<ApiResponse<RenderJobResponse>>;
|
|
15
18
|
export interface RenderJobResponse {
|
|
16
19
|
job_id: string;
|
|
17
20
|
status: string;
|
package/dist/render.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* variable set fails fast.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.submitRemotionCompositionRenderJob = submitRemotionCompositionRenderJob;
|
|
12
13
|
exports.submitImageRenderJob = submitImageRenderJob;
|
|
13
14
|
exports.submitVideoRenderJob = submitVideoRenderJob;
|
|
14
15
|
exports.getRenderJobStatus = getRenderJobStatus;
|
|
@@ -18,6 +19,8 @@ exports.submitScreenshotAnimationRenderJob = submitScreenshotAnimationRenderJob;
|
|
|
18
19
|
exports.submitAutoCaptionRenderJob = submitAutoCaptionRenderJob;
|
|
19
20
|
exports.submitInstagramDmRenderJob = submitInstagramDmRenderJob;
|
|
20
21
|
exports.submitIMessageDmRenderJob = submitIMessageDmRenderJob;
|
|
22
|
+
const zod_1 = require("zod");
|
|
23
|
+
const remotion_composition_1 = require("./render/types/remotion-composition");
|
|
21
24
|
function renderBaseUrl() {
|
|
22
25
|
const url = process.env.UGC_RENDER_URL?.trim();
|
|
23
26
|
if (!url) {
|
|
@@ -26,6 +29,25 @@ function renderBaseUrl() {
|
|
|
26
29
|
return url.replace(/\/+$/, '');
|
|
27
30
|
}
|
|
28
31
|
const MAX_RETRIES = 3;
|
|
32
|
+
/** Submit TSX source and props; UGC owns registration and bundling. */
|
|
33
|
+
async function submitRemotionCompositionRenderJob(params) {
|
|
34
|
+
const parsed = remotion_composition_1.remotionCompositionSchema.safeParse(params);
|
|
35
|
+
if (!parsed.success)
|
|
36
|
+
return { ok: false, code: 400, message: parsed.error.message };
|
|
37
|
+
const response = await renderFetch('/submit-job', {
|
|
38
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
39
|
+
body: JSON.stringify({ config: { _compositionType: 'remotion-composition', ...parsed.data },
|
|
40
|
+
output_type: 'video', video_codec: 'h264' }),
|
|
41
|
+
});
|
|
42
|
+
const data = await response.json();
|
|
43
|
+
const result = zod_1.z.object({ job_id: zod_1.z.string(), status: zod_1.z.string(), output_type: zod_1.z.string(), message: zod_1.z.string() }).safeParse(data);
|
|
44
|
+
if (!response.ok || !result.success || result.data.status === 'error') {
|
|
45
|
+
const error = zod_1.z.object({ error: zod_1.z.string() }).safeParse(data);
|
|
46
|
+
return { ok: false, code: response.ok ? 400 : response.status,
|
|
47
|
+
message: error.success ? error.data.error : 'Failed to submit Remotion composition' };
|
|
48
|
+
}
|
|
49
|
+
return { ok: true, code: 200, message: 'Remotion composition submitted', data: result.data };
|
|
50
|
+
}
|
|
29
51
|
/**
|
|
30
52
|
* Fetch wrapper for every render worker call: retries network errors, 429 and
|
|
31
53
|
* 5xx with exponential backoff; returns 4xx responses to the caller unchanged.
|
package/dist/types.d.ts
CHANGED