@adforge-adgeniq/render 0.1.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.
@@ -0,0 +1,348 @@
1
+ // src/remotion/AdForgeComposition.tsx
2
+ import {
3
+ AbsoluteFill as AbsoluteFill8,
4
+ Sequence,
5
+ useVideoConfig as useVideoConfig3
6
+ } from "remotion";
7
+
8
+ // src/remotion/scenes/AvatarScene.tsx
9
+ import { AbsoluteFill, Video, useCurrentFrame, interpolate } from "remotion";
10
+ import { jsx } from "react/jsx-runtime";
11
+ function AvatarScene({ url, layout, layoutConfig, durationFrames }) {
12
+ const frame = useCurrentFrame();
13
+ const opacity = interpolate(frame, [0, 6], [0, 1], { extrapolateRight: "clamp" });
14
+ const fadeOutOpacity = interpolate(frame, [durationFrames - 6, durationFrames], [1, 0], { extrapolateLeft: "clamp" });
15
+ const finalOpacity = Math.min(opacity, fadeOutOpacity);
16
+ if (!url) {
17
+ return /* @__PURE__ */ jsx(AbsoluteFill, { style: { background: "#1a1a2e", opacity: finalOpacity, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx("span", { style: { color: "#666", fontSize: 32 }, children: "Avatar" }) });
18
+ }
19
+ if (layout === "pip") {
20
+ const { pipAvatarLeft, pipAvatarTop, pipAvatarWidth, width, height } = layoutConfig;
21
+ const pw = Math.round(width * pipAvatarWidth);
22
+ const ph = Math.round(pw * (16 / 9));
23
+ return /* @__PURE__ */ jsx(AbsoluteFill, { style: { opacity: finalOpacity }, children: /* @__PURE__ */ jsx("div", { style: {
24
+ position: "absolute",
25
+ left: Math.round(width * pipAvatarLeft),
26
+ top: Math.round(height * pipAvatarTop),
27
+ width: pw,
28
+ height: ph,
29
+ borderRadius: 12,
30
+ overflow: "hidden",
31
+ boxShadow: "0 4px 24px rgba(0,0,0,0.6)"
32
+ }, children: /* @__PURE__ */ jsx(Video, { src: url, style: { width: "100%", height: "100%", objectFit: "cover" } }) }) });
33
+ }
34
+ return /* @__PURE__ */ jsx(AbsoluteFill, { style: { opacity: finalOpacity }, children: /* @__PURE__ */ jsx(Video, { src: url, style: { width: "100%", height: "100%", objectFit: "cover" } }) });
35
+ }
36
+
37
+ // src/remotion/scenes/BrollScene.tsx
38
+ import { AbsoluteFill as AbsoluteFill2, Img, Video as Video2, useCurrentFrame as useCurrentFrame2, interpolate as interpolate2 } from "remotion";
39
+ import { jsx as jsx2 } from "react/jsx-runtime";
40
+ var IMAGE_EXTS = /\.(jpg|jpeg|png|webp|gif)(\?|$)/i;
41
+ function BrollScene({ url, motion, durationFrames, layoutConfig }) {
42
+ const frame = useCurrentFrame2();
43
+ const opacity = interpolate2(frame, [0, 8, durationFrames - 8, durationFrames], [0, 1, 1, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
44
+ const isKenBurnsOut = motion === "kenburns_out";
45
+ const scaleStart = isKenBurnsOut ? 1.35 : 1;
46
+ const scaleEnd = isKenBurnsOut ? 1 : 1.35;
47
+ const scale = interpolate2(frame, [0, durationFrames], [scaleStart, scaleEnd], { extrapolateRight: "clamp" });
48
+ if (!url) {
49
+ return /* @__PURE__ */ jsx2(AbsoluteFill2, { style: { background: "#111118", opacity, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx2("span", { style: { color: "#555", fontSize: 28 }, children: "B-Roll" }) });
50
+ }
51
+ const isImage = IMAGE_EXTS.test(url);
52
+ const { width, height } = layoutConfig;
53
+ return /* @__PURE__ */ jsx2(AbsoluteFill2, { style: { opacity, overflow: "hidden" }, children: isImage ? /* @__PURE__ */ jsx2(
54
+ Img,
55
+ {
56
+ src: url,
57
+ style: {
58
+ width: "100%",
59
+ height: "100%",
60
+ objectFit: "cover",
61
+ transform: `scale(${scale})`,
62
+ transformOrigin: "center center"
63
+ }
64
+ }
65
+ ) : /* @__PURE__ */ jsx2(Video2, { src: url, style: { width, height, objectFit: "cover" } }) });
66
+ }
67
+
68
+ // src/remotion/scenes/TextCardScene.tsx
69
+ import { AbsoluteFill as AbsoluteFill3, useCurrentFrame as useCurrentFrame3, interpolate as interpolate3 } from "remotion";
70
+ import { jsx as jsx3 } from "react/jsx-runtime";
71
+ function TextCardScene({ captions, durationFrames, layoutConfig }) {
72
+ const frame = useCurrentFrame3();
73
+ const opacity = interpolate3(frame, [0, 8, durationFrames - 8, durationFrames], [0, 1, 1, 0], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
74
+ const text = captions.map((c) => c.text).join(" ");
75
+ const fontSize = layoutConfig.captionFontSize * 1.2;
76
+ return /* @__PURE__ */ jsx3(AbsoluteFill3, { style: {
77
+ background: "linear-gradient(135deg, #0d0d1a 0%, #1a1a3e 100%)",
78
+ opacity,
79
+ display: "flex",
80
+ alignItems: "center",
81
+ justifyContent: "center",
82
+ padding: `0 ${layoutConfig.captionMarginSide * 2}px`
83
+ }, children: /* @__PURE__ */ jsx3("p", { style: {
84
+ color: "white",
85
+ fontSize,
86
+ fontWeight: 800,
87
+ textAlign: "center",
88
+ lineHeight: 1.25,
89
+ fontFamily: "'Arial Black', Arial, sans-serif",
90
+ textShadow: "0 2px 16px rgba(0,0,0,0.8)",
91
+ margin: 0
92
+ }, children: text }) });
93
+ }
94
+
95
+ // src/remotion/captions/KaraokeCaptions.tsx
96
+ import { AbsoluteFill as AbsoluteFill4, useCurrentFrame as useCurrentFrame4, useVideoConfig, interpolate as interpolate4 } from "remotion";
97
+ import { jsx as jsx4 } from "react/jsx-runtime";
98
+ function KaraokeCaptions({ captions, sceneStartS, layout }) {
99
+ const frame = useCurrentFrame4();
100
+ const { fps } = useVideoConfig();
101
+ const currentS = sceneStartS + frame / fps;
102
+ const active = captions.find(
103
+ (c) => currentS >= c.start_s && currentS < c.end_s
104
+ );
105
+ if (!active) return null;
106
+ const { captionFontSize, captionMarginBottom, captionMarginSide, height } = layout;
107
+ const progress = (currentS - active.start_s) / (active.end_s - active.start_s);
108
+ const scale = interpolate4(progress, [0, 0.1, 0.9, 1], [0.92, 1, 1, 0.95]);
109
+ return /* @__PURE__ */ jsx4(AbsoluteFill4, { style: { pointerEvents: "none" }, children: /* @__PURE__ */ jsx4("div", { style: {
110
+ position: "absolute",
111
+ bottom: captionMarginBottom,
112
+ left: captionMarginSide,
113
+ right: captionMarginSide,
114
+ display: "flex",
115
+ justifyContent: "center"
116
+ }, children: /* @__PURE__ */ jsx4("span", { style: {
117
+ display: "inline-block",
118
+ background: "rgba(0,0,0,0.72)",
119
+ color: "#FFE600",
120
+ fontSize: captionFontSize,
121
+ fontWeight: 900,
122
+ fontFamily: "'Arial Black', Arial, sans-serif",
123
+ padding: "6px 16px",
124
+ borderRadius: 8,
125
+ transform: `scale(${scale})`,
126
+ textShadow: "0 1px 4px rgba(0,0,0,0.9)",
127
+ lineHeight: 1.3,
128
+ textAlign: "center"
129
+ }, children: active.text }) }) });
130
+ }
131
+
132
+ // src/remotion/captions/BlockCaptions.tsx
133
+ import { AbsoluteFill as AbsoluteFill5, useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig2, interpolate as interpolate5 } from "remotion";
134
+ import { jsx as jsx5 } from "react/jsx-runtime";
135
+ function BlockCaptions({ captions, sceneStartS, layout }) {
136
+ const frame = useCurrentFrame5();
137
+ const { fps } = useVideoConfig2();
138
+ const currentS = sceneStartS + frame / fps;
139
+ const active = captions.filter(
140
+ (c) => currentS >= c.start_s && currentS < c.end_s + 0.5
141
+ );
142
+ if (!active.length) return null;
143
+ const { captionFontSize, captionMarginBottom, captionMarginSide } = layout;
144
+ const text = active.map((c) => c.text).join(" ");
145
+ const opacity = interpolate5(frame, [0, 4], [0, 1], { extrapolateRight: "clamp" });
146
+ return /* @__PURE__ */ jsx5(AbsoluteFill5, { style: { pointerEvents: "none", opacity }, children: /* @__PURE__ */ jsx5("div", { style: {
147
+ position: "absolute",
148
+ bottom: captionMarginBottom,
149
+ left: captionMarginSide,
150
+ right: captionMarginSide,
151
+ textAlign: "center"
152
+ }, children: /* @__PURE__ */ jsx5("span", { style: {
153
+ display: "inline-block",
154
+ background: "rgba(0,0,0,0.68)",
155
+ color: "white",
156
+ fontSize: captionFontSize * 0.9,
157
+ fontWeight: 700,
158
+ fontFamily: "Arial, sans-serif",
159
+ padding: "8px 20px",
160
+ borderRadius: 6,
161
+ lineHeight: 1.4
162
+ }, children: text }) }) });
163
+ }
164
+
165
+ // src/remotion/EndCard.tsx
166
+ import { AbsoluteFill as AbsoluteFill6, useCurrentFrame as useCurrentFrame6, interpolate as interpolate6 } from "remotion";
167
+ import { jsx as jsx6, jsxs } from "react/jsx-runtime";
168
+ function EndCard({ endCard, layout }) {
169
+ const frame = useCurrentFrame6();
170
+ const opacity = interpolate6(frame, [0, 15], [0, 1], { extrapolateRight: "clamp" });
171
+ const translateY = interpolate6(frame, [0, 15], [24, 0], { extrapolateRight: "clamp" });
172
+ const { captionFontSize } = layout;
173
+ return /* @__PURE__ */ jsx6(AbsoluteFill6, { style: {
174
+ background: "linear-gradient(160deg, #0d0d1a 0%, #1a1a4a 100%)",
175
+ display: "flex",
176
+ flexDirection: "column",
177
+ alignItems: "center",
178
+ justifyContent: "center",
179
+ gap: 24,
180
+ opacity
181
+ }, children: /* @__PURE__ */ jsxs("div", { style: { transform: `translateY(${translateY}px)`, textAlign: "center" }, children: [
182
+ /* @__PURE__ */ jsx6("p", { style: {
183
+ color: "#FFE600",
184
+ fontSize: captionFontSize * 1.4,
185
+ fontWeight: 900,
186
+ fontFamily: "'Arial Black', Arial, sans-serif",
187
+ margin: "0 0 12px"
188
+ }, children: endCard.cta_text }),
189
+ /* @__PURE__ */ jsx6("p", { style: {
190
+ color: "rgba(255,255,255,0.7)",
191
+ fontSize: captionFontSize * 0.75,
192
+ fontFamily: "Arial, sans-serif",
193
+ margin: 0
194
+ }, children: endCard.url_display })
195
+ ] }) });
196
+ }
197
+
198
+ // src/remotion/Watermark.tsx
199
+ import { AbsoluteFill as AbsoluteFill7 } from "remotion";
200
+ import { jsx as jsx7 } from "react/jsx-runtime";
201
+ function Watermark({ layout }) {
202
+ return /* @__PURE__ */ jsx7(AbsoluteFill7, { style: { pointerEvents: "none" }, children: /* @__PURE__ */ jsx7("div", { style: {
203
+ position: "absolute",
204
+ top: Math.round(layout.height * 0.04),
205
+ left: 0,
206
+ right: 0,
207
+ display: "flex",
208
+ justifyContent: "center"
209
+ }, children: /* @__PURE__ */ jsx7("span", { style: {
210
+ background: "rgba(0,0,0,0.45)",
211
+ color: "rgba(255,255,255,0.70)",
212
+ fontSize: Math.round(layout.captionFontSize * 0.55),
213
+ fontFamily: "Arial, sans-serif",
214
+ fontWeight: 600,
215
+ padding: "4px 14px",
216
+ borderRadius: 6,
217
+ letterSpacing: 1
218
+ }, children: "Made with AdForge" }) }) });
219
+ }
220
+
221
+ // src/remotion/layout.ts
222
+ var LAYOUTS = {
223
+ "9:16": {
224
+ width: 1080,
225
+ height: 1920,
226
+ pipAvatarLeft: 0.03,
227
+ pipAvatarTop: 0.55,
228
+ pipAvatarWidth: 0.35,
229
+ captionMarginBottom: 260,
230
+ captionMarginSide: 40,
231
+ captionFontSize: 52
232
+ },
233
+ "16:9": {
234
+ width: 1920,
235
+ height: 1080,
236
+ pipAvatarLeft: 0.65,
237
+ pipAvatarTop: 0.05,
238
+ pipAvatarWidth: 0.3,
239
+ captionMarginBottom: 120,
240
+ captionMarginSide: 80,
241
+ captionFontSize: 42
242
+ },
243
+ "1:1": {
244
+ width: 1080,
245
+ height: 1080,
246
+ pipAvatarLeft: 0.02,
247
+ pipAvatarTop: 0.55,
248
+ pipAvatarWidth: 0.35,
249
+ captionMarginBottom: 140,
250
+ captionMarginSide: 40,
251
+ captionFontSize: 46
252
+ }
253
+ };
254
+ function getLayout(aspect) {
255
+ return LAYOUTS[aspect];
256
+ }
257
+
258
+ // src/remotion/AdForgeComposition.tsx
259
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
260
+ var COMPOSITION_ID = "AdForge";
261
+ function AdForgeComposition({
262
+ storyboard,
263
+ aspect,
264
+ captionStyle,
265
+ watermark = false,
266
+ assetUrls = {},
267
+ avatarUrls = {}
268
+ }) {
269
+ const { fps } = useVideoConfig3();
270
+ const layout = getLayout(aspect);
271
+ let sceneStart = 0;
272
+ const sceneElements = [];
273
+ for (const scene of storyboard.scenes) {
274
+ const durationFrames = Math.round(scene.duration_s * fps);
275
+ const startFrame = Math.round(sceneStart * fps);
276
+ let inner = null;
277
+ if (scene.type === "avatar") {
278
+ const url = scene.avatar_render_id ? avatarUrls[scene.avatar_render_id] : void 0;
279
+ inner = /* @__PURE__ */ jsx8(
280
+ AvatarScene,
281
+ {
282
+ url,
283
+ layout: scene.layout ?? "fullframe",
284
+ layoutConfig: layout,
285
+ durationFrames
286
+ }
287
+ );
288
+ } else if (scene.type === "broll" || scene.type === "product_still") {
289
+ const url = scene.asset_id ? assetUrls[scene.asset_id] : void 0;
290
+ inner = /* @__PURE__ */ jsx8(
291
+ BrollScene,
292
+ {
293
+ url,
294
+ motion: scene.motion,
295
+ durationFrames,
296
+ layoutConfig: layout
297
+ }
298
+ );
299
+ } else {
300
+ inner = /* @__PURE__ */ jsx8(
301
+ TextCardScene,
302
+ {
303
+ captions: scene.captions,
304
+ durationFrames,
305
+ layoutConfig: layout
306
+ }
307
+ );
308
+ }
309
+ const captionOverlay = captionStyle === "KARAOKE" ? /* @__PURE__ */ jsx8(
310
+ KaraokeCaptions,
311
+ {
312
+ captions: scene.captions,
313
+ sceneStartS: sceneStart,
314
+ layout
315
+ }
316
+ ) : captionStyle === "BLOCK" ? /* @__PURE__ */ jsx8(
317
+ BlockCaptions,
318
+ {
319
+ captions: scene.captions,
320
+ sceneStartS: sceneStart,
321
+ layout
322
+ }
323
+ ) : null;
324
+ sceneElements.push(
325
+ /* @__PURE__ */ jsx8(Sequence, { from: startFrame, durationInFrames: durationFrames, children: /* @__PURE__ */ jsxs2(AbsoluteFill8, { children: [
326
+ inner,
327
+ captionOverlay
328
+ ] }) }, scene.id)
329
+ );
330
+ sceneStart += scene.duration_s;
331
+ }
332
+ if (storyboard.end_card) {
333
+ const endCardStart = Math.round(sceneStart * fps);
334
+ const endCardDuration = Math.round(3 * fps);
335
+ sceneElements.push(
336
+ /* @__PURE__ */ jsx8(Sequence, { from: endCardStart, durationInFrames: endCardDuration, children: /* @__PURE__ */ jsx8(EndCard, { endCard: storyboard.end_card, layout }) }, "end-card")
337
+ );
338
+ }
339
+ return /* @__PURE__ */ jsxs2(AbsoluteFill8, { style: { background: "#0d0d12" }, children: [
340
+ sceneElements,
341
+ watermark && /* @__PURE__ */ jsx8(Watermark, { layout })
342
+ ] });
343
+ }
344
+ export {
345
+ AdForgeComposition,
346
+ COMPOSITION_ID,
347
+ getLayout
348
+ };
@@ -0,0 +1,16 @@
1
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
2
+
3
+ /**
4
+ * Storyboard utility helpers — shared between worker, web, and tests.
5
+ * This file is imported by "use client" components; it must remain Zod-free.
6
+ * For server-side validation, import parseStoryboard from ./validate instead.
7
+ */
8
+
9
+ /** Total duration of all scenes in seconds */
10
+ declare function storyboardDurationS(sb: StoryboardJson): number;
11
+ /** Estimated credit cost for rendering: 5 credits per aspect per 30s */
12
+ declare function estimateRenderCredits(sb: StoryboardJson, aspects: number): number;
13
+ /** Assign start_s values based on scene durations (for storyboards from LLM that lack them) */
14
+ declare function assignStartTimes(sb: StoryboardJson): StoryboardJson;
15
+
16
+ export { assignStartTimes, estimateRenderCredits, storyboardDurationS };
@@ -0,0 +1,16 @@
1
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
2
+
3
+ /**
4
+ * Storyboard utility helpers — shared between worker, web, and tests.
5
+ * This file is imported by "use client" components; it must remain Zod-free.
6
+ * For server-side validation, import parseStoryboard from ./validate instead.
7
+ */
8
+
9
+ /** Total duration of all scenes in seconds */
10
+ declare function storyboardDurationS(sb: StoryboardJson): number;
11
+ /** Estimated credit cost for rendering: 5 credits per aspect per 30s */
12
+ declare function estimateRenderCredits(sb: StoryboardJson, aspects: number): number;
13
+ /** Assign start_s values based on scene durations (for storyboards from LLM that lack them) */
14
+ declare function assignStartTimes(sb: StoryboardJson): StoryboardJson;
15
+
16
+ export { assignStartTimes, estimateRenderCredits, storyboardDurationS };
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/storyboard/utils.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ assignStartTimes: () => assignStartTimes,
24
+ estimateRenderCredits: () => estimateRenderCredits,
25
+ storyboardDurationS: () => storyboardDurationS
26
+ });
27
+ module.exports = __toCommonJS(utils_exports);
28
+ function storyboardDurationS(sb) {
29
+ return sb.scenes.reduce((sum, s) => sum + s.duration_s, 0);
30
+ }
31
+ function estimateRenderCredits(sb, aspects) {
32
+ const durationS = storyboardDurationS(sb);
33
+ return Math.ceil(durationS / 30) * 5 * aspects;
34
+ }
35
+ function assignStartTimes(sb) {
36
+ let cursor = 0;
37
+ const scenes = sb.scenes.map((s) => {
38
+ const scene = { ...s, start_s: cursor };
39
+ cursor += s.duration_s;
40
+ return scene;
41
+ });
42
+ return { ...sb, scenes };
43
+ }
44
+ // Annotate the CommonJS export names for ESM import in node:
45
+ 0 && (module.exports = {
46
+ assignStartTimes,
47
+ estimateRenderCredits,
48
+ storyboardDurationS
49
+ });
@@ -0,0 +1,10 @@
1
+ import {
2
+ assignStartTimes,
3
+ estimateRenderCredits,
4
+ storyboardDurationS
5
+ } from "../chunk-IU6GCMDG.mjs";
6
+ export {
7
+ assignStartTimes,
8
+ estimateRenderCredits,
9
+ storyboardDurationS
10
+ };
@@ -0,0 +1,12 @@
1
+ export { StoryboardJsonSchema } from '@adforge-adgeniq/shared/schemas';
2
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
3
+
4
+ /**
5
+ * Server-side storyboard validation — imports Zod via @adforge-adgeniq/shared/schemas.
6
+ * Do NOT import this from any "use client" component or browser bundle.
7
+ */
8
+
9
+ /** Validate and parse raw JSON as a StoryboardJson */
10
+ declare function parseStoryboard(raw: unknown): StoryboardJson;
11
+
12
+ export { parseStoryboard };
@@ -0,0 +1,12 @@
1
+ export { StoryboardJsonSchema } from '@adforge-adgeniq/shared/schemas';
2
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
3
+
4
+ /**
5
+ * Server-side storyboard validation — imports Zod via @adforge-adgeniq/shared/schemas.
6
+ * Do NOT import this from any "use client" component or browser bundle.
7
+ */
8
+
9
+ /** Validate and parse raw JSON as a StoryboardJson */
10
+ declare function parseStoryboard(raw: unknown): StoryboardJson;
11
+
12
+ export { parseStoryboard };
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/storyboard/validate.ts
21
+ var validate_exports = {};
22
+ __export(validate_exports, {
23
+ StoryboardJsonSchema: () => import_schemas.StoryboardJsonSchema,
24
+ parseStoryboard: () => parseStoryboard
25
+ });
26
+ module.exports = __toCommonJS(validate_exports);
27
+ var import_schemas = require("@adforge-adgeniq/shared/schemas");
28
+ function parseStoryboard(raw) {
29
+ return import_schemas.StoryboardJsonSchema.parse(raw);
30
+ }
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ StoryboardJsonSchema,
34
+ parseStoryboard
35
+ });
@@ -0,0 +1,9 @@
1
+ // src/storyboard/validate.ts
2
+ import { StoryboardJsonSchema } from "@adforge-adgeniq/shared/schemas";
3
+ function parseStoryboard(raw) {
4
+ return StoryboardJsonSchema.parse(raw);
5
+ }
6
+ export {
7
+ StoryboardJsonSchema,
8
+ parseStoryboard
9
+ };
@@ -0,0 +1,37 @@
1
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
2
+
3
+ type Aspect = "9:16" | "16:9" | "1:1";
4
+ type Resolution = "720p" | "1080p";
5
+ type CaptionStyle = "KARAOKE" | "BLOCK" | "NONE";
6
+ interface RenderJob {
7
+ videoProjectId: string;
8
+ storyboardId: string;
9
+ workspaceId: string;
10
+ aspect: Aspect;
11
+ resolution: Resolution;
12
+ captionStyle: CaptionStyle;
13
+ storyboard: StoryboardJson;
14
+ /** Map of assetId → local file path */
15
+ assetPaths: Record<string, string>;
16
+ /** Map of renderId → local file path (avatar video) */
17
+ avatarRenderPaths: Record<string, string>;
18
+ outputPath: string;
19
+ watermark: boolean;
20
+ }
21
+ interface RenderResult {
22
+ r2Key: string;
23
+ url: string;
24
+ durationMs: number;
25
+ costUsd: number;
26
+ /** Asset IDs that were expected but missing at render time (e.g. deleted files). */
27
+ skippedAssets?: string[];
28
+ }
29
+ interface AspectDimensions {
30
+ width: number;
31
+ height: number;
32
+ safeAreaTop: number;
33
+ safeAreaBottom: number;
34
+ safeAreaSide: number;
35
+ }
36
+
37
+ export type { Aspect, AspectDimensions, CaptionStyle, RenderJob, RenderResult, Resolution };
@@ -0,0 +1,37 @@
1
+ import { StoryboardJson } from '@adforge-adgeniq/shared';
2
+
3
+ type Aspect = "9:16" | "16:9" | "1:1";
4
+ type Resolution = "720p" | "1080p";
5
+ type CaptionStyle = "KARAOKE" | "BLOCK" | "NONE";
6
+ interface RenderJob {
7
+ videoProjectId: string;
8
+ storyboardId: string;
9
+ workspaceId: string;
10
+ aspect: Aspect;
11
+ resolution: Resolution;
12
+ captionStyle: CaptionStyle;
13
+ storyboard: StoryboardJson;
14
+ /** Map of assetId → local file path */
15
+ assetPaths: Record<string, string>;
16
+ /** Map of renderId → local file path (avatar video) */
17
+ avatarRenderPaths: Record<string, string>;
18
+ outputPath: string;
19
+ watermark: boolean;
20
+ }
21
+ interface RenderResult {
22
+ r2Key: string;
23
+ url: string;
24
+ durationMs: number;
25
+ costUsd: number;
26
+ /** Asset IDs that were expected but missing at render time (e.g. deleted files). */
27
+ skippedAssets?: string[];
28
+ }
29
+ interface AspectDimensions {
30
+ width: number;
31
+ height: number;
32
+ safeAreaTop: number;
33
+ safeAreaBottom: number;
34
+ safeAreaSide: number;
35
+ }
36
+
37
+ export type { Aspect, AspectDimensions, CaptionStyle, RenderJob, RenderResult, Resolution };
package/dist/types.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
package/dist/types.mjs ADDED
File without changes