@koda-sl/baker-cli 0.39.29-dev.994437bd → 0.66.2
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 +1754 -7
- package/canvas/avocado-tutorial.json +89 -0
- package/canvas/hello-world-composition/index.html +83 -0
- package/canvas/hello-world-composition/meta.json +41 -0
- package/canvas/hello-world-overlay.json +37 -0
- package/canvas/phone-scroll-composition/index.html +141 -0
- package/canvas/phone-scroll-composition/meta.json +39 -0
- package/canvas/tiktok-captions-composition/index.html +126 -0
- package/canvas/tiktok-captions-composition/meta.json +46 -0
- package/canvas/video-overlay-composition/index.html +239 -0
- package/canvas/video-overlay-composition/meta.json +29 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/ads/meta/creatives.js +1 -1
- package/dist/commands/canvas/catalog.d.ts +2 -0
- package/dist/commands/canvas/catalog.d.ts.map +1 -0
- package/dist/commands/canvas/catalog.js +13 -0
- package/dist/commands/canvas/catalog.js.map +1 -0
- package/dist/commands/canvas/index.d.ts +2 -0
- package/dist/commands/canvas/index.d.ts.map +1 -0
- package/dist/commands/canvas/index.js +32 -0
- package/dist/commands/canvas/index.js.map +1 -0
- package/dist/commands/canvas/inspect.d.ts +16 -0
- package/dist/commands/canvas/inspect.d.ts.map +1 -0
- package/dist/commands/canvas/inspect.js +115 -0
- package/dist/commands/canvas/inspect.js.map +1 -0
- package/dist/commands/canvas/run.d.ts +24 -0
- package/dist/commands/canvas/run.d.ts.map +1 -0
- package/dist/commands/canvas/run.js +56 -0
- package/dist/commands/canvas/run.js.map +1 -0
- package/dist/commands/canvas/scaffold-static-ad.d.ts +40 -0
- package/dist/commands/canvas/scaffold-static-ad.d.ts.map +1 -0
- package/dist/commands/canvas/scaffold-static-ad.js +265 -0
- package/dist/commands/canvas/scaffold-static-ad.js.map +1 -0
- package/dist/commands/canvas/scaffold-video.d.ts +44 -0
- package/dist/commands/canvas/scaffold-video.d.ts.map +1 -0
- package/dist/commands/canvas/scaffold-video.js +235 -0
- package/dist/commands/canvas/scaffold-video.js.map +1 -0
- package/dist/commands/canvas/validate.d.ts +8 -0
- package/dist/commands/canvas/validate.d.ts.map +1 -0
- package/dist/commands/canvas/validate.js +37 -0
- package/dist/commands/canvas/validate.js.map +1 -0
- package/dist/commands/images/find.d.ts +1 -1
- package/dist/commands/images/find.d.ts.map +1 -1
- package/dist/commands/images/find.js +12 -3
- package/dist/commands/images/find.js.map +1 -1
- package/dist/commands/images/google.d.ts +1 -1
- package/dist/commands/images/google.d.ts.map +1 -1
- package/dist/commands/images/google.js +12 -3
- package/dist/commands/images/google.js.map +1 -1
- package/dist/commands/images/stock.d.ts +1 -1
- package/dist/commands/images/stock.d.ts.map +1 -1
- package/dist/commands/images/stock.js +7 -3
- package/dist/commands/images/stock.js.map +1 -1
- package/dist/commands/testimonials/list.d.ts.map +1 -1
- package/dist/commands/testimonials/list.js +21 -6
- package/dist/commands/testimonials/list.js.map +1 -1
- package/dist/commands/testimonials/search.d.ts.map +1 -1
- package/dist/commands/testimonials/search.js +21 -6
- package/dist/commands/testimonials/search.js.map +1 -1
- package/dist/commands/testimonials/search.test.js +3 -3
- package/dist/commands/testimonials/search.test.js.map +1 -1
- package/dist/engine/client/backend-client.d.ts +50 -0
- package/dist/engine/client/backend-client.d.ts.map +1 -0
- package/dist/engine/client/backend-client.js +20 -0
- package/dist/engine/client/backend-client.js.map +1 -0
- package/dist/engine/client/env.d.ts +7 -0
- package/dist/engine/client/env.d.ts.map +1 -0
- package/dist/engine/client/env.js +18 -0
- package/dist/engine/client/env.js.map +1 -0
- package/dist/engine/client/http.d.ts +56 -0
- package/dist/engine/client/http.d.ts.map +1 -0
- package/dist/engine/client/http.js +168 -0
- package/dist/engine/client/http.js.map +1 -0
- package/dist/engine/engine/cache-key.d.ts +19 -0
- package/dist/engine/engine/cache-key.d.ts.map +1 -0
- package/dist/engine/engine/cache-key.js +33 -0
- package/dist/engine/engine/cache-key.js.map +1 -0
- package/dist/engine/engine/canonical.d.ts +14 -0
- package/dist/engine/engine/canonical.d.ts.map +1 -0
- package/dist/engine/engine/canonical.js +53 -0
- package/dist/engine/engine/canonical.js.map +1 -0
- package/dist/engine/engine/composition-hash.d.ts +14 -0
- package/dist/engine/engine/composition-hash.d.ts.map +1 -0
- package/dist/engine/engine/composition-hash.js +51 -0
- package/dist/engine/engine/composition-hash.js.map +1 -0
- package/dist/engine/engine/composition-meta.d.ts +77 -0
- package/dist/engine/engine/composition-meta.d.ts.map +1 -0
- package/dist/engine/engine/composition-meta.js +199 -0
- package/dist/engine/engine/composition-meta.js.map +1 -0
- package/dist/engine/engine/context.d.ts +16 -0
- package/dist/engine/engine/context.d.ts.map +1 -0
- package/dist/engine/engine/context.js +2 -0
- package/dist/engine/engine/context.js.map +1 -0
- package/dist/engine/engine/define.d.ts +69 -0
- package/dist/engine/engine/define.d.ts.map +1 -0
- package/dist/engine/engine/define.js +9 -0
- package/dist/engine/engine/define.js.map +1 -0
- package/dist/engine/engine/didyoumean.d.ts +2 -0
- package/dist/engine/engine/didyoumean.d.ts.map +1 -0
- package/dist/engine/engine/didyoumean.js +58 -0
- package/dist/engine/engine/didyoumean.js.map +1 -0
- package/dist/engine/engine/errors.d.ts +41 -0
- package/dist/engine/engine/errors.d.ts.map +1 -0
- package/dist/engine/engine/errors.js +45 -0
- package/dist/engine/engine/errors.js.map +1 -0
- package/dist/engine/engine/executor.d.ts +72 -0
- package/dist/engine/engine/executor.d.ts.map +1 -0
- package/dist/engine/engine/executor.js +445 -0
- package/dist/engine/engine/executor.js.map +1 -0
- package/dist/engine/engine/refs.d.ts +12 -0
- package/dist/engine/engine/refs.d.ts.map +1 -0
- package/dist/engine/engine/refs.js +48 -0
- package/dist/engine/engine/refs.js.map +1 -0
- package/dist/engine/engine/registry.d.ts +11 -0
- package/dist/engine/engine/registry.d.ts.map +1 -0
- package/dist/engine/engine/registry.js +26 -0
- package/dist/engine/engine/registry.js.map +1 -0
- package/dist/engine/engine/scheduler.d.ts +10 -0
- package/dist/engine/engine/scheduler.d.ts.map +1 -0
- package/dist/engine/engine/scheduler.js +89 -0
- package/dist/engine/engine/scheduler.js.map +1 -0
- package/dist/engine/engine/validator.d.ts +31 -0
- package/dist/engine/engine/validator.d.ts.map +1 -0
- package/dist/engine/engine/validator.js +501 -0
- package/dist/engine/engine/validator.js.map +1 -0
- package/dist/engine/index.d.ts +33 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +104 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/lib/ulid.d.ts +3 -0
- package/dist/engine/lib/ulid.d.ts.map +1 -0
- package/dist/engine/lib/ulid.js +36 -0
- package/dist/engine/lib/ulid.js.map +1 -0
- package/dist/engine/models/canvas-ad-params.test.d.ts +2 -0
- package/dist/engine/models/canvas-ad-params.test.d.ts.map +1 -0
- package/dist/engine/models/canvas-ad-params.test.js +60 -0
- package/dist/engine/models/canvas-ad-params.test.js.map +1 -0
- package/dist/engine/models/registry.d.ts +63 -0
- package/dist/engine/models/registry.d.ts.map +1 -0
- package/dist/engine/models/registry.js +432 -0
- package/dist/engine/models/registry.js.map +1 -0
- package/dist/engine/models/validateParams.d.ts +38 -0
- package/dist/engine/models/validateParams.d.ts.map +1 -0
- package/dist/engine/models/validateParams.js +166 -0
- package/dist/engine/models/validateParams.js.map +1 -0
- package/dist/engine/nodes/ingest.d.ts +113 -0
- package/dist/engine/nodes/ingest.d.ts.map +1 -0
- package/dist/engine/nodes/ingest.js +555 -0
- package/dist/engine/nodes/ingest.js.map +1 -0
- package/dist/engine/nodes/ingest.svg.test.d.ts +2 -0
- package/dist/engine/nodes/ingest.svg.test.d.ts.map +1 -0
- package/dist/engine/nodes/ingest.svg.test.js +30 -0
- package/dist/engine/nodes/ingest.svg.test.js.map +1 -0
- package/dist/engine/nodes/local/audioTimeline.d.ts +82 -0
- package/dist/engine/nodes/local/audioTimeline.d.ts.map +1 -0
- package/dist/engine/nodes/local/audioTimeline.js +97 -0
- package/dist/engine/nodes/local/audioTimeline.js.map +1 -0
- package/dist/engine/nodes/local/ffmpeg.d.ts +56 -0
- package/dist/engine/nodes/local/ffmpeg.d.ts.map +1 -0
- package/dist/engine/nodes/local/ffmpeg.js +50 -0
- package/dist/engine/nodes/local/ffmpeg.js.map +1 -0
- package/dist/engine/nodes/local/fontSpecimen.d.ts +50 -0
- package/dist/engine/nodes/local/fontSpecimen.d.ts.map +1 -0
- package/dist/engine/nodes/local/fontSpecimen.js +198 -0
- package/dist/engine/nodes/local/fontSpecimen.js.map +1 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.d.ts +116 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.d.ts.map +1 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.js +230 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.js.map +1 -0
- package/dist/engine/nodes/local/hyperframe.d.ts +123 -0
- package/dist/engine/nodes/local/hyperframe.d.ts.map +1 -0
- package/dist/engine/nodes/local/hyperframe.js +367 -0
- package/dist/engine/nodes/local/hyperframe.js.map +1 -0
- package/dist/engine/nodes/local/imagemagick.d.ts +56 -0
- package/dist/engine/nodes/local/imagemagick.d.ts.map +1 -0
- package/dist/engine/nodes/local/imagemagick.js +71 -0
- package/dist/engine/nodes/local/imagemagick.js.map +1 -0
- package/dist/engine/nodes/local/lib/assets.d.ts +20 -0
- package/dist/engine/nodes/local/lib/assets.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/assets.js +40 -0
- package/dist/engine/nodes/local/lib/assets.js.map +1 -0
- package/dist/engine/nodes/local/lib/cli-runner.d.ts +78 -0
- package/dist/engine/nodes/local/lib/cli-runner.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/cli-runner.js +254 -0
- package/dist/engine/nodes/local/lib/cli-runner.js.map +1 -0
- package/dist/engine/nodes/local/lib/ffmpeg.d.ts +23 -0
- package/dist/engine/nodes/local/lib/ffmpeg.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/ffmpeg.js +75 -0
- package/dist/engine/nodes/local/lib/ffmpeg.js.map +1 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts +2 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.js +47 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.js.map +1 -0
- package/dist/engine/nodes/local/lib/templating.d.ts +22 -0
- package/dist/engine/nodes/local/lib/templating.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/templating.js +85 -0
- package/dist/engine/nodes/local/lib/templating.js.map +1 -0
- package/dist/engine/nodes/local/text.d.ts +6 -0
- package/dist/engine/nodes/local/text.d.ts.map +1 -0
- package/dist/engine/nodes/local/text.js +15 -0
- package/dist/engine/nodes/local/text.js.map +1 -0
- package/dist/engine/nodes/remote/delegate.d.ts +25 -0
- package/dist/engine/nodes/remote/delegate.d.ts.map +1 -0
- package/dist/engine/nodes/remote/delegate.js +160 -0
- package/dist/engine/nodes/remote/delegate.js.map +1 -0
- package/dist/engine/nodes/remote/dialogue.d.ts +34 -0
- package/dist/engine/nodes/remote/dialogue.d.ts.map +1 -0
- package/dist/engine/nodes/remote/dialogue.js +54 -0
- package/dist/engine/nodes/remote/dialogue.js.map +1 -0
- package/dist/engine/nodes/remote/image.d.ts +42 -0
- package/dist/engine/nodes/remote/image.d.ts.map +1 -0
- package/dist/engine/nodes/remote/image.js +43 -0
- package/dist/engine/nodes/remote/image.js.map +1 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.d.ts +30 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.js +42 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.js.map +1 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts +39 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.js +37 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.js.map +1 -0
- package/dist/engine/nodes/remote/imageDescribe.d.ts +29 -0
- package/dist/engine/nodes/remote/imageDescribe.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageDescribe.js +25 -0
- package/dist/engine/nodes/remote/imageDescribe.js.map +1 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.d.ts +34 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.js +38 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.js.map +1 -0
- package/dist/engine/nodes/remote/imageSearch.d.ts +18 -0
- package/dist/engine/nodes/remote/imageSearch.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageSearch.js +22 -0
- package/dist/engine/nodes/remote/imageSearch.js.map +1 -0
- package/dist/engine/nodes/remote/imageSelect.d.ts +39 -0
- package/dist/engine/nodes/remote/imageSelect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageSelect.js +45 -0
- package/dist/engine/nodes/remote/imageSelect.js.map +1 -0
- package/dist/engine/nodes/remote/music.d.ts +45 -0
- package/dist/engine/nodes/remote/music.d.ts.map +1 -0
- package/dist/engine/nodes/remote/music.js +73 -0
- package/dist/engine/nodes/remote/music.js.map +1 -0
- package/dist/engine/nodes/remote/soundEffect.d.ts +21 -0
- package/dist/engine/nodes/remote/soundEffect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/soundEffect.js +41 -0
- package/dist/engine/nodes/remote/soundEffect.js.map +1 -0
- package/dist/engine/nodes/remote/textGenerate.d.ts +21 -0
- package/dist/engine/nodes/remote/textGenerate.d.ts.map +1 -0
- package/dist/engine/nodes/remote/textGenerate.js +27 -0
- package/dist/engine/nodes/remote/textGenerate.js.map +1 -0
- package/dist/engine/nodes/remote/tts.d.ts +45 -0
- package/dist/engine/nodes/remote/tts.d.ts.map +1 -0
- package/dist/engine/nodes/remote/tts.js +66 -0
- package/dist/engine/nodes/remote/tts.js.map +1 -0
- package/dist/engine/nodes/remote/video.d.ts +58 -0
- package/dist/engine/nodes/remote/video.d.ts.map +1 -0
- package/dist/engine/nodes/remote/video.js +44 -0
- package/dist/engine/nodes/remote/video.js.map +1 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts +30 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.js +29 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.js.map +1 -0
- package/dist/engine/nodes/remote/videoDeconstruct.d.ts +61 -0
- package/dist/engine/nodes/remote/videoDeconstruct.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoDeconstruct.js +40 -0
- package/dist/engine/nodes/remote/videoDeconstruct.js.map +1 -0
- package/dist/engine/nodes/remote/videoLipsync.d.ts +37 -0
- package/dist/engine/nodes/remote/videoLipsync.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoLipsync.js +26 -0
- package/dist/engine/nodes/remote/videoLipsync.js.map +1 -0
- package/dist/engine/nodes/remote/videoTranscribe.d.ts +116 -0
- package/dist/engine/nodes/remote/videoTranscribe.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoTranscribe.js +123 -0
- package/dist/engine/nodes/remote/videoTranscribe.js.map +1 -0
- package/dist/engine/nodes/remote/voiceSelect.d.ts +28 -0
- package/dist/engine/nodes/remote/voiceSelect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/voiceSelect.js +25 -0
- package/dist/engine/nodes/remote/voiceSelect.js.map +1 -0
- package/dist/engine/scaffold/staticAd.d.ts +44 -0
- package/dist/engine/scaffold/staticAd.d.ts.map +1 -0
- package/dist/engine/scaffold/staticAd.js +243 -0
- package/dist/engine/scaffold/staticAd.js.map +1 -0
- package/dist/engine/scaffold/video.d.ts +56 -0
- package/dist/engine/scaffold/video.d.ts.map +1 -0
- package/dist/engine/scaffold/video.js +709 -0
- package/dist/engine/scaffold/video.js.map +1 -0
- package/dist/engine/schema/canvas.d.ts +41 -0
- package/dist/engine/schema/canvas.d.ts.map +1 -0
- package/dist/engine/schema/canvas.js +67 -0
- package/dist/engine/schema/canvas.js.map +1 -0
- package/dist/engine/schema/catalog.d.ts +25 -0
- package/dist/engine/schema/catalog.d.ts.map +1 -0
- package/dist/engine/schema/catalog.js +48 -0
- package/dist/engine/schema/catalog.js.map +1 -0
- package/dist/engine/schema/primitives.d.ts +6 -0
- package/dist/engine/schema/primitives.d.ts.map +1 -0
- package/dist/engine/schema/primitives.js +4 -0
- package/dist/engine/schema/primitives.js.map +1 -0
- package/dist/engine/schema/prompts.d.ts +4 -0
- package/dist/engine/schema/prompts.d.ts.map +1 -0
- package/dist/engine/schema/prompts.js +23 -0
- package/dist/engine/schema/prompts.js.map +1 -0
- package/dist/engine/schema/refs.d.ts +113 -0
- package/dist/engine/schema/refs.d.ts.map +1 -0
- package/dist/engine/schema/refs.js +35 -0
- package/dist/engine/schema/refs.js.map +1 -0
- package/dist/engine/storage/asset-store.d.ts +48 -0
- package/dist/engine/storage/asset-store.d.ts.map +1 -0
- package/dist/engine/storage/asset-store.js +166 -0
- package/dist/engine/storage/asset-store.js.map +1 -0
- package/dist/engine/storage/cache-store.d.ts +21 -0
- package/dist/engine/storage/cache-store.d.ts.map +1 -0
- package/dist/engine/storage/cache-store.js +31 -0
- package/dist/engine/storage/cache-store.js.map +1 -0
- package/dist/engine/storage/output-writer.d.ts +18 -0
- package/dist/engine/storage/output-writer.d.ts.map +1 -0
- package/dist/engine/storage/output-writer.js +52 -0
- package/dist/engine/storage/output-writer.js.map +1 -0
- package/dist/engine/storage/sha256.d.ts +2 -0
- package/dist/engine/storage/sha256.d.ts.map +1 -0
- package/dist/engine/storage/sha256.js +7 -0
- package/dist/engine/storage/sha256.js.map +1 -0
- package/package.json +15 -3
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { type CompositionMeta } from "../../engine/composition-meta.ts";
|
|
2
|
+
import type { AssetRef } from "../../schema/refs.ts";
|
|
3
|
+
export declare const hyperframeRenderNode: import("../../engine/define.ts").NodeDefinition<Record<string, {
|
|
4
|
+
sha256: string;
|
|
5
|
+
mime: string;
|
|
6
|
+
kind: "image";
|
|
7
|
+
url?: string | undefined;
|
|
8
|
+
path?: string | undefined;
|
|
9
|
+
metadata?: Record<string, unknown> | undefined;
|
|
10
|
+
width?: number | undefined;
|
|
11
|
+
height?: number | undefined;
|
|
12
|
+
} | {
|
|
13
|
+
sha256: string;
|
|
14
|
+
mime: string;
|
|
15
|
+
kind: "video";
|
|
16
|
+
url?: string | undefined;
|
|
17
|
+
path?: string | undefined;
|
|
18
|
+
metadata?: Record<string, unknown> | undefined;
|
|
19
|
+
width?: number | undefined;
|
|
20
|
+
height?: number | undefined;
|
|
21
|
+
duration_ms?: number | undefined;
|
|
22
|
+
} | {
|
|
23
|
+
sha256: string;
|
|
24
|
+
mime: string;
|
|
25
|
+
kind: "audio";
|
|
26
|
+
url?: string | undefined;
|
|
27
|
+
path?: string | undefined;
|
|
28
|
+
metadata?: Record<string, unknown> | undefined;
|
|
29
|
+
duration_ms?: number | undefined;
|
|
30
|
+
} | {
|
|
31
|
+
sha256: string;
|
|
32
|
+
mime: string;
|
|
33
|
+
kind: "json";
|
|
34
|
+
url?: string | undefined;
|
|
35
|
+
path?: string | undefined;
|
|
36
|
+
metadata?: Record<string, unknown> | undefined;
|
|
37
|
+
} | {
|
|
38
|
+
sha256: string;
|
|
39
|
+
mime: string;
|
|
40
|
+
kind: "text";
|
|
41
|
+
url?: string | undefined;
|
|
42
|
+
path?: string | undefined;
|
|
43
|
+
metadata?: Record<string, unknown> | undefined;
|
|
44
|
+
} | {
|
|
45
|
+
sha256: string;
|
|
46
|
+
mime: string;
|
|
47
|
+
kind: "font";
|
|
48
|
+
url?: string | undefined;
|
|
49
|
+
path?: string | undefined;
|
|
50
|
+
metadata?: Record<string, unknown> | undefined;
|
|
51
|
+
}>, {
|
|
52
|
+
[x: string]: unknown;
|
|
53
|
+
composition: string;
|
|
54
|
+
timeout_ms: number;
|
|
55
|
+
}, {
|
|
56
|
+
video: {
|
|
57
|
+
sha256: string;
|
|
58
|
+
mime: string;
|
|
59
|
+
kind: "image";
|
|
60
|
+
url?: string | undefined;
|
|
61
|
+
path?: string | undefined;
|
|
62
|
+
metadata?: Record<string, unknown> | undefined;
|
|
63
|
+
width?: number | undefined;
|
|
64
|
+
height?: number | undefined;
|
|
65
|
+
} | {
|
|
66
|
+
sha256: string;
|
|
67
|
+
mime: string;
|
|
68
|
+
kind: "video";
|
|
69
|
+
url?: string | undefined;
|
|
70
|
+
path?: string | undefined;
|
|
71
|
+
metadata?: Record<string, unknown> | undefined;
|
|
72
|
+
width?: number | undefined;
|
|
73
|
+
height?: number | undefined;
|
|
74
|
+
duration_ms?: number | undefined;
|
|
75
|
+
} | {
|
|
76
|
+
sha256: string;
|
|
77
|
+
mime: string;
|
|
78
|
+
kind: "audio";
|
|
79
|
+
url?: string | undefined;
|
|
80
|
+
path?: string | undefined;
|
|
81
|
+
metadata?: Record<string, unknown> | undefined;
|
|
82
|
+
duration_ms?: number | undefined;
|
|
83
|
+
} | {
|
|
84
|
+
sha256: string;
|
|
85
|
+
mime: string;
|
|
86
|
+
kind: "json";
|
|
87
|
+
url?: string | undefined;
|
|
88
|
+
path?: string | undefined;
|
|
89
|
+
metadata?: Record<string, unknown> | undefined;
|
|
90
|
+
} | {
|
|
91
|
+
sha256: string;
|
|
92
|
+
mime: string;
|
|
93
|
+
kind: "text";
|
|
94
|
+
url?: string | undefined;
|
|
95
|
+
path?: string | undefined;
|
|
96
|
+
metadata?: Record<string, unknown> | undefined;
|
|
97
|
+
} | {
|
|
98
|
+
sha256: string;
|
|
99
|
+
mime: string;
|
|
100
|
+
kind: "font";
|
|
101
|
+
url?: string | undefined;
|
|
102
|
+
path?: string | undefined;
|
|
103
|
+
metadata?: Record<string, unknown> | undefined;
|
|
104
|
+
};
|
|
105
|
+
}>;
|
|
106
|
+
export declare function resolveCompositionDir(composition: string): Promise<string>;
|
|
107
|
+
/**
|
|
108
|
+
* Validate raw params against the composition's meta.json.
|
|
109
|
+
* Returns issue list (empty = ok). Used by `validateExtra` so canvas
|
|
110
|
+
* validate catches bad params before any render runs.
|
|
111
|
+
*/
|
|
112
|
+
export declare function validateCompositionParams(rawParams: unknown): Promise<{
|
|
113
|
+
path: string;
|
|
114
|
+
message: string;
|
|
115
|
+
}[]>;
|
|
116
|
+
/**
|
|
117
|
+
* Shared input-vs-meta check used by both hyperframe nodes. Throws on:
|
|
118
|
+
* - undeclared input keys (typo / stale canvas)
|
|
119
|
+
* - missing required inputs
|
|
120
|
+
* - kind mismatch (canvas passes an image where video is declared)
|
|
121
|
+
*/
|
|
122
|
+
export declare function assertInputsMatchMeta(inputs: Record<string, AssetRef> | undefined, meta: CompositionMeta, nodeId: string): void;
|
|
123
|
+
//# sourceMappingURL=hyperframe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperframe.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/local/hyperframe.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA4CrD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsE/B,CAAC;AAMH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKhF;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAiDhH;AAyED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,EAC5C,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,MAAM,GACb,IAAI,CAqBN"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { copyFile, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { cpus, tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { hashCompositionDir } from "../../engine/composition-hash.js";
|
|
9
|
+
import { buildParamsSchema, defaultFilenameForInput, loadCompositionMeta, } from "../../engine/composition-meta.js";
|
|
10
|
+
import { defineNode } from "../../engine/define.js";
|
|
11
|
+
import { isAssetRefLike, refToUrl, stageAsset } from "./lib/assets.js";
|
|
12
|
+
import { mapKnownHyperframesError } from "./lib/hyperframe-errors.js";
|
|
13
|
+
import { substituteVariables } from "./lib/templating.js";
|
|
14
|
+
const execFileAsync = promisify(execFile);
|
|
15
|
+
const require_ = createRequire(import.meta.url);
|
|
16
|
+
// Runtime knobs are owned by the canvas-engine — we always render at max
|
|
17
|
+
// quality, mp4, on the controlled E2B sandbox (see
|
|
18
|
+
// `packages/e2b-template/src/template.ts`). The composition's own params
|
|
19
|
+
// (`words_per_group`, `transcript`, etc.) ride alongside via `.catchall` and
|
|
20
|
+
// are validated against the composition's meta.json by `validateExtra`.
|
|
21
|
+
const HyperframeParams = z
|
|
22
|
+
.object({
|
|
23
|
+
composition: z.string().min(1),
|
|
24
|
+
timeout_ms: z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.positive()
|
|
28
|
+
.optional()
|
|
29
|
+
.default(10 * 60 * 1000),
|
|
30
|
+
})
|
|
31
|
+
.catchall(z.unknown());
|
|
32
|
+
// Inputs are dynamic — meta.json declares which keys this composition
|
|
33
|
+
// expects. The node accepts any keyed AssetRef and validates against meta
|
|
34
|
+
// at execute time.
|
|
35
|
+
const HyperframeInputs = z.record(z.string(), z.custom()).optional().default({});
|
|
36
|
+
const HyperframeOutputs = z
|
|
37
|
+
.object({
|
|
38
|
+
video: z.custom(),
|
|
39
|
+
})
|
|
40
|
+
.strict();
|
|
41
|
+
const NODE_OWNED_PARAM_KEYS = new Set(["composition", "timeout_ms"]);
|
|
42
|
+
// Engine-injected: the substitution pass fills these from input asset duration
|
|
43
|
+
// (and the composition's default_duration). Authors must not declare them.
|
|
44
|
+
const ENGINE_INJECTED_TOKENS = new Set(["duration"]);
|
|
45
|
+
export const hyperframeRenderNode = defineNode({
|
|
46
|
+
id: "hyperframe_render",
|
|
47
|
+
version: "6.0.0",
|
|
48
|
+
category: "video",
|
|
49
|
+
location: "local",
|
|
50
|
+
summary: "Render an mp4 by composing an HTML/CSS/GSAP composition over upstream assets. Point `params.composition` at a directory containing `index.html` + `meta.json`. All variables are passed as primitives in `params` and substituted into the composition before render.",
|
|
51
|
+
when_to_use: "Use to add captions, lower-thirds, branded overlays, title cards, or any HTML-driven graphic over a video. " +
|
|
52
|
+
"Point `params.composition` at a directory containing `index.html` + `meta.json`. " +
|
|
53
|
+
"Inputs are keyed by the composition's `meta.json.inputs` map — wire `inputs.<key> = $ref:<node>.<output>`. " +
|
|
54
|
+
"Output resolution/fps come from the composition's `meta.json`; quality, format, and worker count are fixed by the engine for ad-creative delivery.",
|
|
55
|
+
inputs: HyperframeInputs,
|
|
56
|
+
params: HyperframeParams,
|
|
57
|
+
outputs: HyperframeOutputs,
|
|
58
|
+
cost: () => ({ credits: 0, seconds_estimate: 30 }),
|
|
59
|
+
validateExtra: ({ rawParams }) => validateCompositionParams(rawParams),
|
|
60
|
+
cacheKeyExtras: async ({ params }) => {
|
|
61
|
+
const out = {};
|
|
62
|
+
const composition = params.composition;
|
|
63
|
+
if (typeof composition !== "string")
|
|
64
|
+
return out;
|
|
65
|
+
const dir = await resolveCompositionDir(composition).catch(() => null);
|
|
66
|
+
if (!dir)
|
|
67
|
+
return out;
|
|
68
|
+
out.composition_content_sha = await hashCompositionDir(dir);
|
|
69
|
+
return out;
|
|
70
|
+
},
|
|
71
|
+
async execute({ inputs, params, ctx }) {
|
|
72
|
+
const compositionDir = await resolveCompositionDir(params.composition);
|
|
73
|
+
const meta = await loadCompositionMeta(compositionDir);
|
|
74
|
+
const compositionParams = validateAndParseDynamicParams(meta, params);
|
|
75
|
+
const tmp = await mkdtemp(path.join(tmpdir(), "hf-render-"));
|
|
76
|
+
try {
|
|
77
|
+
await copyComposition(compositionDir, tmp);
|
|
78
|
+
await vendorGsap(tmp, ctx);
|
|
79
|
+
const stagedDuration = await stageInputs(tmp, inputs, meta, ctx);
|
|
80
|
+
const duration = stagedDuration ?? meta.default_duration;
|
|
81
|
+
const substitutionValues = await buildSubstitutionValues(compositionParams, meta, duration);
|
|
82
|
+
await substituteCompositionFiles(tmp, substitutionValues);
|
|
83
|
+
await ensureMetaJson(tmp, ctx.nodeId, meta, duration);
|
|
84
|
+
const outputPath = path.join(tmp, "output.mp4");
|
|
85
|
+
await runRender({ tmp, outputPath, params, meta, ctx });
|
|
86
|
+
const bytes = await readFile(outputPath);
|
|
87
|
+
ctx.log(`rendered ${bytes.length} bytes`);
|
|
88
|
+
const ref = await ctx.assets.ingestBytes({
|
|
89
|
+
bytes: Buffer.from(bytes),
|
|
90
|
+
kind: "video",
|
|
91
|
+
mime: "video/mp4",
|
|
92
|
+
metadata: {
|
|
93
|
+
width: meta.width,
|
|
94
|
+
height: meta.height,
|
|
95
|
+
fps: meta.fps,
|
|
96
|
+
duration_ms: Math.round(duration * 1000),
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
return { video: ref };
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await rm(tmp, { recursive: true, force: true }).catch((e) => {
|
|
103
|
+
ctx.log(`warning: tmp cleanup failed (${e.message})`);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Composition resolution + dynamic param validation
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
export async function resolveCompositionDir(composition) {
|
|
112
|
+
const compositionPath = path.isAbsolute(composition) ? composition : path.resolve(process.cwd(), composition);
|
|
113
|
+
const s = await stat(compositionPath);
|
|
114
|
+
if (s.isDirectory())
|
|
115
|
+
return compositionPath;
|
|
116
|
+
return path.dirname(compositionPath);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Validate raw params against the composition's meta.json.
|
|
120
|
+
* Returns issue list (empty = ok). Used by `validateExtra` so canvas
|
|
121
|
+
* validate catches bad params before any render runs.
|
|
122
|
+
*/
|
|
123
|
+
export async function validateCompositionParams(rawParams) {
|
|
124
|
+
const issues = [];
|
|
125
|
+
if (!rawParams || typeof rawParams !== "object")
|
|
126
|
+
return issues;
|
|
127
|
+
const params = rawParams;
|
|
128
|
+
const composition = params.composition;
|
|
129
|
+
if (typeof composition !== "string")
|
|
130
|
+
return issues; // static schema will have flagged it
|
|
131
|
+
let dir;
|
|
132
|
+
try {
|
|
133
|
+
dir = await resolveCompositionDir(composition);
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
issues.push({ path: "params.composition", message: e.message });
|
|
137
|
+
return issues;
|
|
138
|
+
}
|
|
139
|
+
let meta;
|
|
140
|
+
try {
|
|
141
|
+
meta = await loadCompositionMeta(dir);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
issues.push({ path: "params.composition", message: e.message });
|
|
145
|
+
return issues;
|
|
146
|
+
}
|
|
147
|
+
// Pick out only the dynamic (composition-declared) params for the meta-schema check.
|
|
148
|
+
const dynamic = {};
|
|
149
|
+
for (const [k, v] of Object.entries(params)) {
|
|
150
|
+
if (NODE_OWNED_PARAM_KEYS.has(k))
|
|
151
|
+
continue;
|
|
152
|
+
dynamic[k] = v;
|
|
153
|
+
}
|
|
154
|
+
for (const key of Object.keys(dynamic)) {
|
|
155
|
+
if (ENGINE_INJECTED_TOKENS.has(key)) {
|
|
156
|
+
issues.push({
|
|
157
|
+
path: `params.${key}`,
|
|
158
|
+
message: `"${key}" is reserved (auto-injected by the renderer from input duration); remove from params`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const schema = buildParamsSchema(meta);
|
|
163
|
+
const parsed = schema.safeParse(dynamic);
|
|
164
|
+
if (!parsed.success) {
|
|
165
|
+
for (const issue of parsed.error.issues) {
|
|
166
|
+
const tail = issue.path.join(".");
|
|
167
|
+
issues.push({
|
|
168
|
+
path: `params.${tail}`,
|
|
169
|
+
message: issue.message,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return issues;
|
|
174
|
+
}
|
|
175
|
+
function validateAndParseDynamicParams(meta, params) {
|
|
176
|
+
const dynamic = {};
|
|
177
|
+
for (const [k, v] of Object.entries(params)) {
|
|
178
|
+
if (NODE_OWNED_PARAM_KEYS.has(k))
|
|
179
|
+
continue;
|
|
180
|
+
dynamic[k] = v;
|
|
181
|
+
}
|
|
182
|
+
const schema = buildParamsSchema(meta);
|
|
183
|
+
const parsed = schema.safeParse(dynamic);
|
|
184
|
+
if (!parsed.success) {
|
|
185
|
+
const summary = parsed.error.issues.map((i) => `params.${i.path.join(".")}: ${i.message}`).join("; ");
|
|
186
|
+
throw new Error(`hyperframe_render: composition param validation failed — ${summary}`);
|
|
187
|
+
}
|
|
188
|
+
return parsed.data;
|
|
189
|
+
}
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Asset staging
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
async function copyComposition(srcDir, destDir) {
|
|
194
|
+
const { cp } = await import("node:fs/promises");
|
|
195
|
+
await cp(srcDir, destDir, {
|
|
196
|
+
recursive: true,
|
|
197
|
+
filter: (src) => {
|
|
198
|
+
const name = path.basename(src);
|
|
199
|
+
if (name === ".cache" || name === "node_modules" || name === ".git")
|
|
200
|
+
return false;
|
|
201
|
+
return true;
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async function vendorGsap(tmp, ctx) {
|
|
206
|
+
try {
|
|
207
|
+
const gsapMin = require_.resolve("gsap/dist/gsap.min.js");
|
|
208
|
+
await copyFile(gsapMin, path.join(tmp, "gsap.min.js"));
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Stage every input referenced in canvas `inputs` against the composition's
|
|
216
|
+
* declared `meta.inputs` map. Throws on:
|
|
217
|
+
* - missing required input
|
|
218
|
+
* - input kind mismatch (canvas passes an image where video is declared)
|
|
219
|
+
* - undeclared input key
|
|
220
|
+
*
|
|
221
|
+
* Returns the duration of the primary input asset (when a video) so the
|
|
222
|
+
* engine can substitute `{{duration}}`. Falls back to meta.default_duration.
|
|
223
|
+
*/
|
|
224
|
+
async function stageInputs(tmp, inputs, meta, ctx) {
|
|
225
|
+
assertInputsMatchMeta(inputs, meta, "hyperframe_render");
|
|
226
|
+
let primaryDuration = null;
|
|
227
|
+
for (const [key, ref] of Object.entries(inputs ?? {})) {
|
|
228
|
+
const spec = meta.inputs[key];
|
|
229
|
+
if (!spec)
|
|
230
|
+
continue;
|
|
231
|
+
const filename = spec.staged_as ?? defaultFilenameForInput(key, spec.kind);
|
|
232
|
+
await stageAsset(ref, tmp, filename);
|
|
233
|
+
ctx.log(`staged ${spec.kind} → ${filename}`);
|
|
234
|
+
if (spec.kind === "video" && primaryDuration === null) {
|
|
235
|
+
primaryDuration = await probeDurationSeconds(path.join(tmp, filename));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return primaryDuration;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Shared input-vs-meta check used by both hyperframe nodes. Throws on:
|
|
242
|
+
* - undeclared input keys (typo / stale canvas)
|
|
243
|
+
* - missing required inputs
|
|
244
|
+
* - kind mismatch (canvas passes an image where video is declared)
|
|
245
|
+
*/
|
|
246
|
+
export function assertInputsMatchMeta(inputs, meta, nodeId) {
|
|
247
|
+
const declaredKeys = new Set(Object.keys(meta.inputs));
|
|
248
|
+
const providedKeys = new Set(Object.keys(inputs ?? {}));
|
|
249
|
+
for (const key of providedKeys) {
|
|
250
|
+
if (!declaredKeys.has(key)) {
|
|
251
|
+
const declared = [...declaredKeys].join(", ") || "<none>";
|
|
252
|
+
throw new Error(`${nodeId}: inputs.${key} is not declared in composition meta.json (declares: ${declared})`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
for (const [key, spec] of Object.entries(meta.inputs)) {
|
|
256
|
+
if (spec.required && !providedKeys.has(key)) {
|
|
257
|
+
throw new Error(`${nodeId}: inputs.${key} is required (kind=${spec.kind})`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
for (const [key, ref] of Object.entries(inputs ?? {})) {
|
|
261
|
+
const spec = meta.inputs[key];
|
|
262
|
+
if (!spec)
|
|
263
|
+
continue;
|
|
264
|
+
if (ref.kind !== spec.kind) {
|
|
265
|
+
throw new Error(`${nodeId}: inputs.${key} expected kind "${spec.kind}", got "${ref.kind}"`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
// Substitution
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
async function buildSubstitutionValues(compositionParams, meta, duration) {
|
|
273
|
+
const out = {};
|
|
274
|
+
for (const [name, value] of Object.entries(compositionParams)) {
|
|
275
|
+
const spec = meta.params[name];
|
|
276
|
+
if (spec?.kind === "image") {
|
|
277
|
+
out[name] = await coerceImageParam(value);
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
out[name] = value;
|
|
281
|
+
}
|
|
282
|
+
out.duration = duration.toFixed(3);
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
function coerceImageParam(value) {
|
|
286
|
+
if (typeof value === "string")
|
|
287
|
+
return Promise.resolve(value);
|
|
288
|
+
if (isAssetRefLike(value))
|
|
289
|
+
return refToUrl(value);
|
|
290
|
+
throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
|
|
291
|
+
}
|
|
292
|
+
async function substituteCompositionFiles(tmp, values) {
|
|
293
|
+
// Substitute in index.html (the only file Hyperframes loads). Embedded
|
|
294
|
+
// <style>/<script> live inside index.html so a single pass handles all of them.
|
|
295
|
+
const entryPath = path.join(tmp, "index.html");
|
|
296
|
+
const original = await readFile(entryPath, "utf-8");
|
|
297
|
+
const { output, missing } = substituteVariables(original, values);
|
|
298
|
+
if (missing.length > 0) {
|
|
299
|
+
throw new Error(`hyperframe_render: composition references undefined variables: ${missing.map((m) => `{{${m}}}`).join(", ")}. ` +
|
|
300
|
+
`Add to params or to meta.json's params with a default.`);
|
|
301
|
+
}
|
|
302
|
+
await writeFile(entryPath, output, "utf-8");
|
|
303
|
+
}
|
|
304
|
+
async function ensureMetaJson(tmp, nodeId, meta, duration) {
|
|
305
|
+
// Hyperframes itself reads a top-level `meta.json` next to index.html with
|
|
306
|
+
// {id,name,duration,width,height,fps}. We always overwrite with the engine's
|
|
307
|
+
// values so Hyperframes' interpretation matches ours.
|
|
308
|
+
const metaPath = path.join(tmp, "meta.json");
|
|
309
|
+
await writeFile(metaPath, JSON.stringify({
|
|
310
|
+
id: nodeId,
|
|
311
|
+
name: meta.id,
|
|
312
|
+
duration,
|
|
313
|
+
width: meta.width,
|
|
314
|
+
height: meta.height,
|
|
315
|
+
fps: meta.fps,
|
|
316
|
+
}, null, 2), "utf-8");
|
|
317
|
+
}
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
// Render shell-out
|
|
320
|
+
// ---------------------------------------------------------------------------
|
|
321
|
+
// Cap workers at 4 on the controlled sandbox — Hyperframes spins up one
|
|
322
|
+
// headless Chrome per worker and the e2b instance is typically a 4-vCPU box.
|
|
323
|
+
const MAX_WORKERS = 4;
|
|
324
|
+
function workerCount() {
|
|
325
|
+
return Math.max(1, Math.min(MAX_WORKERS, cpus().length));
|
|
326
|
+
}
|
|
327
|
+
async function runRender(opts) {
|
|
328
|
+
const { tmp, outputPath, params, meta, ctx } = opts;
|
|
329
|
+
const args = buildRenderArgs(tmp, outputPath, meta);
|
|
330
|
+
ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps from ${path.basename(tmp)}`);
|
|
331
|
+
try {
|
|
332
|
+
await execFileAsync("npx", args, { timeout: params.timeout_ms, maxBuffer: 64 * 1024 * 1024 });
|
|
333
|
+
}
|
|
334
|
+
catch (e) {
|
|
335
|
+
const stderr = e.stderr ?? "";
|
|
336
|
+
const stdout = e.stdout ?? "";
|
|
337
|
+
const detail = stderr || stdout || e.message;
|
|
338
|
+
const friendly = mapKnownHyperframesError(detail);
|
|
339
|
+
throw new Error(`hyperframe_render: render failed\n${friendly ?? detail.slice(0, 4000)}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function buildRenderArgs(tmp, outputPath, meta) {
|
|
343
|
+
return [
|
|
344
|
+
"hyperframes",
|
|
345
|
+
"render",
|
|
346
|
+
tmp,
|
|
347
|
+
"--output",
|
|
348
|
+
outputPath,
|
|
349
|
+
"--fps",
|
|
350
|
+
String(meta.fps),
|
|
351
|
+
"--quality",
|
|
352
|
+
"high",
|
|
353
|
+
"--format",
|
|
354
|
+
"mp4",
|
|
355
|
+
"--workers",
|
|
356
|
+
String(workerCount()),
|
|
357
|
+
];
|
|
358
|
+
}
|
|
359
|
+
async function probeDurationSeconds(filePath) {
|
|
360
|
+
const { stdout } = await execFileAsync("ffprobe", ["-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", filePath], { encoding: "utf-8" });
|
|
361
|
+
const seconds = Number.parseFloat(stdout.trim());
|
|
362
|
+
if (!Number.isFinite(seconds)) {
|
|
363
|
+
throw new Error(`hyperframe_render: ffprobe returned invalid duration: ${stdout}`);
|
|
364
|
+
}
|
|
365
|
+
return seconds;
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=hyperframe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperframe.js","sourceRoot":"","sources":["../../../../src/engine/nodes/local/hyperframe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export declare const imagemagickNode: import("../../engine/define.ts").NodeDefinition<Record<string, unknown>, {
|
|
2
|
+
args: string[];
|
|
3
|
+
outputs: Record<string, {
|
|
4
|
+
kind: "video" | "image" | "audio";
|
|
5
|
+
ext: string;
|
|
6
|
+
}>;
|
|
7
|
+
}, Record<string, {
|
|
8
|
+
sha256: string;
|
|
9
|
+
mime: string;
|
|
10
|
+
kind: "image";
|
|
11
|
+
url?: string | undefined;
|
|
12
|
+
path?: string | undefined;
|
|
13
|
+
metadata?: Record<string, unknown> | undefined;
|
|
14
|
+
width?: number | undefined;
|
|
15
|
+
height?: number | undefined;
|
|
16
|
+
} | {
|
|
17
|
+
sha256: string;
|
|
18
|
+
mime: string;
|
|
19
|
+
kind: "video";
|
|
20
|
+
url?: string | undefined;
|
|
21
|
+
path?: string | undefined;
|
|
22
|
+
metadata?: Record<string, unknown> | undefined;
|
|
23
|
+
width?: number | undefined;
|
|
24
|
+
height?: number | undefined;
|
|
25
|
+
duration_ms?: number | undefined;
|
|
26
|
+
} | {
|
|
27
|
+
sha256: string;
|
|
28
|
+
mime: string;
|
|
29
|
+
kind: "audio";
|
|
30
|
+
url?: string | undefined;
|
|
31
|
+
path?: string | undefined;
|
|
32
|
+
metadata?: Record<string, unknown> | undefined;
|
|
33
|
+
duration_ms?: number | undefined;
|
|
34
|
+
} | {
|
|
35
|
+
sha256: string;
|
|
36
|
+
mime: string;
|
|
37
|
+
kind: "json";
|
|
38
|
+
url?: string | undefined;
|
|
39
|
+
path?: string | undefined;
|
|
40
|
+
metadata?: Record<string, unknown> | undefined;
|
|
41
|
+
} | {
|
|
42
|
+
sha256: string;
|
|
43
|
+
mime: string;
|
|
44
|
+
kind: "text";
|
|
45
|
+
url?: string | undefined;
|
|
46
|
+
path?: string | undefined;
|
|
47
|
+
metadata?: Record<string, unknown> | undefined;
|
|
48
|
+
} | {
|
|
49
|
+
sha256: string;
|
|
50
|
+
mime: string;
|
|
51
|
+
kind: "font";
|
|
52
|
+
url?: string | undefined;
|
|
53
|
+
path?: string | undefined;
|
|
54
|
+
metadata?: Record<string, unknown> | undefined;
|
|
55
|
+
}>>;
|
|
56
|
+
//# sourceMappingURL=imagemagick.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagemagick.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/local/imagemagick.ts"],"names":[],"mappings":"AA+CA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgC1B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { defineNode } from "../../engine/define.js";
|
|
5
|
+
import { getToolVersion, runCli } from "./lib/cli-runner.js";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const OutputDecl = z
|
|
8
|
+
.object({
|
|
9
|
+
kind: z.enum(["image", "video", "audio"]),
|
|
10
|
+
ext: z.string().min(1).max(8),
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
const ImageMagickParams = z
|
|
14
|
+
.object({
|
|
15
|
+
args: z.array(z.string()).min(1),
|
|
16
|
+
outputs: z.record(z.string(), OutputDecl).default({}),
|
|
17
|
+
})
|
|
18
|
+
.strict();
|
|
19
|
+
const ImageMagickInputs = z.record(z.string(), z.unknown());
|
|
20
|
+
const ImageMagickOutputs = z.record(z.string(), z.custom());
|
|
21
|
+
/**
|
|
22
|
+
* Resolve which ImageMagick binary to use. Prefer `magick` (v7+); fall back to
|
|
23
|
+
* `convert` (v6). Memoized per process; if neither is on PATH we fail at
|
|
24
|
+
* execute time with a clear message.
|
|
25
|
+
*/
|
|
26
|
+
let resolvedBin;
|
|
27
|
+
async function resolveBin() {
|
|
28
|
+
if (resolvedBin)
|
|
29
|
+
return resolvedBin;
|
|
30
|
+
for (const candidate of ["magick", "convert"]) {
|
|
31
|
+
try {
|
|
32
|
+
await execFileAsync(candidate, ["-version"], { encoding: "utf-8" });
|
|
33
|
+
resolvedBin = candidate;
|
|
34
|
+
return candidate;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// try next candidate
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw new Error("imagemagick: neither `magick` nor `convert` found on PATH");
|
|
41
|
+
}
|
|
42
|
+
export const imagemagickNode = defineNode({
|
|
43
|
+
id: "imagemagick",
|
|
44
|
+
version: "1.0.0",
|
|
45
|
+
category: "image",
|
|
46
|
+
location: "local",
|
|
47
|
+
summary: "Local ImageMagick passthrough. Declare inputs, declare outputs, write the argv you'd type on the command line. Inputs are staged into a tmp dir and reached via `{{in.<slot>}}`; declared outputs are allocated at `{{out.<name>}}` and ingested as assets when the run completes.",
|
|
48
|
+
when_to_use: "Use whenever you'd reach for ImageMagick on the command line: resize, crop, composite, convert formats, annotate, montage, fx. Pass the full argv as `params.args` (no shell — argv array, no string interpolation). " +
|
|
49
|
+
"Wire input images via `inputs.<slot>` (single AssetRef) or `inputs.<slot>: [...]` (array, addressed as `{{in.<slot>.0}}`, …). " +
|
|
50
|
+
"Declare every output file under `params.outputs` (name → {kind, ext}); the engine allocates the path, you reference it with `{{out.<name>}}`. " +
|
|
51
|
+
"Requires `magick` (v7+) or `convert` (v6) on PATH. URL-style inputs and raw filesystem paths in args are rejected — keep everything in the engine's asset model.",
|
|
52
|
+
inputs: ImageMagickInputs,
|
|
53
|
+
params: ImageMagickParams,
|
|
54
|
+
outputs: ImageMagickOutputs,
|
|
55
|
+
cost: () => ({ credits: 0, seconds_estimate: 3 }),
|
|
56
|
+
async cacheKeyExtras() {
|
|
57
|
+
const bin = await resolveBin().catch(() => "imagemagick:unavailable");
|
|
58
|
+
return { imagemagick_version: await getToolVersion(bin) };
|
|
59
|
+
},
|
|
60
|
+
async execute({ inputs, params, ctx }) {
|
|
61
|
+
const bin = await resolveBin();
|
|
62
|
+
return await runCli({
|
|
63
|
+
bin,
|
|
64
|
+
args: params.args,
|
|
65
|
+
inputs: inputs,
|
|
66
|
+
outputs: params.outputs,
|
|
67
|
+
ctx,
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=imagemagick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagemagick.js","sourceRoot":"","sources":["../../../../src/engine/nodes/local/imagemagick.ts"],"names":[],"mappings":"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"}
|