@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.
Files changed (323) hide show
  1. package/README.md +1754 -7
  2. package/canvas/avocado-tutorial.json +89 -0
  3. package/canvas/hello-world-composition/index.html +83 -0
  4. package/canvas/hello-world-composition/meta.json +41 -0
  5. package/canvas/hello-world-overlay.json +37 -0
  6. package/canvas/phone-scroll-composition/index.html +141 -0
  7. package/canvas/phone-scroll-composition/meta.json +39 -0
  8. package/canvas/tiktok-captions-composition/index.html +126 -0
  9. package/canvas/tiktok-captions-composition/meta.json +46 -0
  10. package/canvas/video-overlay-composition/index.html +239 -0
  11. package/canvas/video-overlay-composition/meta.json +29 -0
  12. package/dist/cli.js +2 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/ads/meta/creatives.js +1 -1
  15. package/dist/commands/canvas/catalog.d.ts +2 -0
  16. package/dist/commands/canvas/catalog.d.ts.map +1 -0
  17. package/dist/commands/canvas/catalog.js +13 -0
  18. package/dist/commands/canvas/catalog.js.map +1 -0
  19. package/dist/commands/canvas/index.d.ts +2 -0
  20. package/dist/commands/canvas/index.d.ts.map +1 -0
  21. package/dist/commands/canvas/index.js +32 -0
  22. package/dist/commands/canvas/index.js.map +1 -0
  23. package/dist/commands/canvas/inspect.d.ts +16 -0
  24. package/dist/commands/canvas/inspect.d.ts.map +1 -0
  25. package/dist/commands/canvas/inspect.js +115 -0
  26. package/dist/commands/canvas/inspect.js.map +1 -0
  27. package/dist/commands/canvas/run.d.ts +24 -0
  28. package/dist/commands/canvas/run.d.ts.map +1 -0
  29. package/dist/commands/canvas/run.js +56 -0
  30. package/dist/commands/canvas/run.js.map +1 -0
  31. package/dist/commands/canvas/scaffold-static-ad.d.ts +40 -0
  32. package/dist/commands/canvas/scaffold-static-ad.d.ts.map +1 -0
  33. package/dist/commands/canvas/scaffold-static-ad.js +265 -0
  34. package/dist/commands/canvas/scaffold-static-ad.js.map +1 -0
  35. package/dist/commands/canvas/scaffold-video.d.ts +44 -0
  36. package/dist/commands/canvas/scaffold-video.d.ts.map +1 -0
  37. package/dist/commands/canvas/scaffold-video.js +235 -0
  38. package/dist/commands/canvas/scaffold-video.js.map +1 -0
  39. package/dist/commands/canvas/validate.d.ts +8 -0
  40. package/dist/commands/canvas/validate.d.ts.map +1 -0
  41. package/dist/commands/canvas/validate.js +37 -0
  42. package/dist/commands/canvas/validate.js.map +1 -0
  43. package/dist/commands/images/find.d.ts +1 -1
  44. package/dist/commands/images/find.d.ts.map +1 -1
  45. package/dist/commands/images/find.js +12 -3
  46. package/dist/commands/images/find.js.map +1 -1
  47. package/dist/commands/images/google.d.ts +1 -1
  48. package/dist/commands/images/google.d.ts.map +1 -1
  49. package/dist/commands/images/google.js +12 -3
  50. package/dist/commands/images/google.js.map +1 -1
  51. package/dist/commands/images/stock.d.ts +1 -1
  52. package/dist/commands/images/stock.d.ts.map +1 -1
  53. package/dist/commands/images/stock.js +7 -3
  54. package/dist/commands/images/stock.js.map +1 -1
  55. package/dist/commands/testimonials/list.d.ts.map +1 -1
  56. package/dist/commands/testimonials/list.js +21 -6
  57. package/dist/commands/testimonials/list.js.map +1 -1
  58. package/dist/commands/testimonials/search.d.ts.map +1 -1
  59. package/dist/commands/testimonials/search.js +21 -6
  60. package/dist/commands/testimonials/search.js.map +1 -1
  61. package/dist/commands/testimonials/search.test.js +3 -3
  62. package/dist/commands/testimonials/search.test.js.map +1 -1
  63. package/dist/engine/client/backend-client.d.ts +50 -0
  64. package/dist/engine/client/backend-client.d.ts.map +1 -0
  65. package/dist/engine/client/backend-client.js +20 -0
  66. package/dist/engine/client/backend-client.js.map +1 -0
  67. package/dist/engine/client/env.d.ts +7 -0
  68. package/dist/engine/client/env.d.ts.map +1 -0
  69. package/dist/engine/client/env.js +18 -0
  70. package/dist/engine/client/env.js.map +1 -0
  71. package/dist/engine/client/http.d.ts +56 -0
  72. package/dist/engine/client/http.d.ts.map +1 -0
  73. package/dist/engine/client/http.js +168 -0
  74. package/dist/engine/client/http.js.map +1 -0
  75. package/dist/engine/engine/cache-key.d.ts +19 -0
  76. package/dist/engine/engine/cache-key.d.ts.map +1 -0
  77. package/dist/engine/engine/cache-key.js +33 -0
  78. package/dist/engine/engine/cache-key.js.map +1 -0
  79. package/dist/engine/engine/canonical.d.ts +14 -0
  80. package/dist/engine/engine/canonical.d.ts.map +1 -0
  81. package/dist/engine/engine/canonical.js +53 -0
  82. package/dist/engine/engine/canonical.js.map +1 -0
  83. package/dist/engine/engine/composition-hash.d.ts +14 -0
  84. package/dist/engine/engine/composition-hash.d.ts.map +1 -0
  85. package/dist/engine/engine/composition-hash.js +51 -0
  86. package/dist/engine/engine/composition-hash.js.map +1 -0
  87. package/dist/engine/engine/composition-meta.d.ts +77 -0
  88. package/dist/engine/engine/composition-meta.d.ts.map +1 -0
  89. package/dist/engine/engine/composition-meta.js +199 -0
  90. package/dist/engine/engine/composition-meta.js.map +1 -0
  91. package/dist/engine/engine/context.d.ts +16 -0
  92. package/dist/engine/engine/context.d.ts.map +1 -0
  93. package/dist/engine/engine/context.js +2 -0
  94. package/dist/engine/engine/context.js.map +1 -0
  95. package/dist/engine/engine/define.d.ts +69 -0
  96. package/dist/engine/engine/define.d.ts.map +1 -0
  97. package/dist/engine/engine/define.js +9 -0
  98. package/dist/engine/engine/define.js.map +1 -0
  99. package/dist/engine/engine/didyoumean.d.ts +2 -0
  100. package/dist/engine/engine/didyoumean.d.ts.map +1 -0
  101. package/dist/engine/engine/didyoumean.js +58 -0
  102. package/dist/engine/engine/didyoumean.js.map +1 -0
  103. package/dist/engine/engine/errors.d.ts +41 -0
  104. package/dist/engine/engine/errors.d.ts.map +1 -0
  105. package/dist/engine/engine/errors.js +45 -0
  106. package/dist/engine/engine/errors.js.map +1 -0
  107. package/dist/engine/engine/executor.d.ts +72 -0
  108. package/dist/engine/engine/executor.d.ts.map +1 -0
  109. package/dist/engine/engine/executor.js +445 -0
  110. package/dist/engine/engine/executor.js.map +1 -0
  111. package/dist/engine/engine/refs.d.ts +12 -0
  112. package/dist/engine/engine/refs.d.ts.map +1 -0
  113. package/dist/engine/engine/refs.js +48 -0
  114. package/dist/engine/engine/refs.js.map +1 -0
  115. package/dist/engine/engine/registry.d.ts +11 -0
  116. package/dist/engine/engine/registry.d.ts.map +1 -0
  117. package/dist/engine/engine/registry.js +26 -0
  118. package/dist/engine/engine/registry.js.map +1 -0
  119. package/dist/engine/engine/scheduler.d.ts +10 -0
  120. package/dist/engine/engine/scheduler.d.ts.map +1 -0
  121. package/dist/engine/engine/scheduler.js +89 -0
  122. package/dist/engine/engine/scheduler.js.map +1 -0
  123. package/dist/engine/engine/validator.d.ts +31 -0
  124. package/dist/engine/engine/validator.d.ts.map +1 -0
  125. package/dist/engine/engine/validator.js +501 -0
  126. package/dist/engine/engine/validator.js.map +1 -0
  127. package/dist/engine/index.d.ts +33 -0
  128. package/dist/engine/index.d.ts.map +1 -0
  129. package/dist/engine/index.js +104 -0
  130. package/dist/engine/index.js.map +1 -0
  131. package/dist/engine/lib/ulid.d.ts +3 -0
  132. package/dist/engine/lib/ulid.d.ts.map +1 -0
  133. package/dist/engine/lib/ulid.js +36 -0
  134. package/dist/engine/lib/ulid.js.map +1 -0
  135. package/dist/engine/models/canvas-ad-params.test.d.ts +2 -0
  136. package/dist/engine/models/canvas-ad-params.test.d.ts.map +1 -0
  137. package/dist/engine/models/canvas-ad-params.test.js +60 -0
  138. package/dist/engine/models/canvas-ad-params.test.js.map +1 -0
  139. package/dist/engine/models/registry.d.ts +63 -0
  140. package/dist/engine/models/registry.d.ts.map +1 -0
  141. package/dist/engine/models/registry.js +432 -0
  142. package/dist/engine/models/registry.js.map +1 -0
  143. package/dist/engine/models/validateParams.d.ts +38 -0
  144. package/dist/engine/models/validateParams.d.ts.map +1 -0
  145. package/dist/engine/models/validateParams.js +166 -0
  146. package/dist/engine/models/validateParams.js.map +1 -0
  147. package/dist/engine/nodes/ingest.d.ts +113 -0
  148. package/dist/engine/nodes/ingest.d.ts.map +1 -0
  149. package/dist/engine/nodes/ingest.js +555 -0
  150. package/dist/engine/nodes/ingest.js.map +1 -0
  151. package/dist/engine/nodes/ingest.svg.test.d.ts +2 -0
  152. package/dist/engine/nodes/ingest.svg.test.d.ts.map +1 -0
  153. package/dist/engine/nodes/ingest.svg.test.js +30 -0
  154. package/dist/engine/nodes/ingest.svg.test.js.map +1 -0
  155. package/dist/engine/nodes/local/audioTimeline.d.ts +82 -0
  156. package/dist/engine/nodes/local/audioTimeline.d.ts.map +1 -0
  157. package/dist/engine/nodes/local/audioTimeline.js +97 -0
  158. package/dist/engine/nodes/local/audioTimeline.js.map +1 -0
  159. package/dist/engine/nodes/local/ffmpeg.d.ts +56 -0
  160. package/dist/engine/nodes/local/ffmpeg.d.ts.map +1 -0
  161. package/dist/engine/nodes/local/ffmpeg.js +50 -0
  162. package/dist/engine/nodes/local/ffmpeg.js.map +1 -0
  163. package/dist/engine/nodes/local/fontSpecimen.d.ts +50 -0
  164. package/dist/engine/nodes/local/fontSpecimen.d.ts.map +1 -0
  165. package/dist/engine/nodes/local/fontSpecimen.js +198 -0
  166. package/dist/engine/nodes/local/fontSpecimen.js.map +1 -0
  167. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts +116 -0
  168. package/dist/engine/nodes/local/hyperframe-snapshot.d.ts.map +1 -0
  169. package/dist/engine/nodes/local/hyperframe-snapshot.js +230 -0
  170. package/dist/engine/nodes/local/hyperframe-snapshot.js.map +1 -0
  171. package/dist/engine/nodes/local/hyperframe.d.ts +123 -0
  172. package/dist/engine/nodes/local/hyperframe.d.ts.map +1 -0
  173. package/dist/engine/nodes/local/hyperframe.js +367 -0
  174. package/dist/engine/nodes/local/hyperframe.js.map +1 -0
  175. package/dist/engine/nodes/local/imagemagick.d.ts +56 -0
  176. package/dist/engine/nodes/local/imagemagick.d.ts.map +1 -0
  177. package/dist/engine/nodes/local/imagemagick.js +71 -0
  178. package/dist/engine/nodes/local/imagemagick.js.map +1 -0
  179. package/dist/engine/nodes/local/lib/assets.d.ts +20 -0
  180. package/dist/engine/nodes/local/lib/assets.d.ts.map +1 -0
  181. package/dist/engine/nodes/local/lib/assets.js +40 -0
  182. package/dist/engine/nodes/local/lib/assets.js.map +1 -0
  183. package/dist/engine/nodes/local/lib/cli-runner.d.ts +78 -0
  184. package/dist/engine/nodes/local/lib/cli-runner.d.ts.map +1 -0
  185. package/dist/engine/nodes/local/lib/cli-runner.js +254 -0
  186. package/dist/engine/nodes/local/lib/cli-runner.js.map +1 -0
  187. package/dist/engine/nodes/local/lib/ffmpeg.d.ts +23 -0
  188. package/dist/engine/nodes/local/lib/ffmpeg.d.ts.map +1 -0
  189. package/dist/engine/nodes/local/lib/ffmpeg.js +75 -0
  190. package/dist/engine/nodes/local/lib/ffmpeg.js.map +1 -0
  191. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts +2 -0
  192. package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts.map +1 -0
  193. package/dist/engine/nodes/local/lib/hyperframe-errors.js +47 -0
  194. package/dist/engine/nodes/local/lib/hyperframe-errors.js.map +1 -0
  195. package/dist/engine/nodes/local/lib/templating.d.ts +22 -0
  196. package/dist/engine/nodes/local/lib/templating.d.ts.map +1 -0
  197. package/dist/engine/nodes/local/lib/templating.js +85 -0
  198. package/dist/engine/nodes/local/lib/templating.js.map +1 -0
  199. package/dist/engine/nodes/local/text.d.ts +6 -0
  200. package/dist/engine/nodes/local/text.d.ts.map +1 -0
  201. package/dist/engine/nodes/local/text.js +15 -0
  202. package/dist/engine/nodes/local/text.js.map +1 -0
  203. package/dist/engine/nodes/remote/delegate.d.ts +25 -0
  204. package/dist/engine/nodes/remote/delegate.d.ts.map +1 -0
  205. package/dist/engine/nodes/remote/delegate.js +160 -0
  206. package/dist/engine/nodes/remote/delegate.js.map +1 -0
  207. package/dist/engine/nodes/remote/dialogue.d.ts +34 -0
  208. package/dist/engine/nodes/remote/dialogue.d.ts.map +1 -0
  209. package/dist/engine/nodes/remote/dialogue.js +54 -0
  210. package/dist/engine/nodes/remote/dialogue.js.map +1 -0
  211. package/dist/engine/nodes/remote/image.d.ts +42 -0
  212. package/dist/engine/nodes/remote/image.d.ts.map +1 -0
  213. package/dist/engine/nodes/remote/image.js +43 -0
  214. package/dist/engine/nodes/remote/image.js.map +1 -0
  215. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts +30 -0
  216. package/dist/engine/nodes/remote/imageAspectAdapt.d.ts.map +1 -0
  217. package/dist/engine/nodes/remote/imageAspectAdapt.js +42 -0
  218. package/dist/engine/nodes/remote/imageAspectAdapt.js.map +1 -0
  219. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts +39 -0
  220. package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts.map +1 -0
  221. package/dist/engine/nodes/remote/imageBackgroundRemove.js +37 -0
  222. package/dist/engine/nodes/remote/imageBackgroundRemove.js.map +1 -0
  223. package/dist/engine/nodes/remote/imageDescribe.d.ts +29 -0
  224. package/dist/engine/nodes/remote/imageDescribe.d.ts.map +1 -0
  225. package/dist/engine/nodes/remote/imageDescribe.js +25 -0
  226. package/dist/engine/nodes/remote/imageDescribe.js.map +1 -0
  227. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts +34 -0
  228. package/dist/engine/nodes/remote/imageReferenceSheet.d.ts.map +1 -0
  229. package/dist/engine/nodes/remote/imageReferenceSheet.js +38 -0
  230. package/dist/engine/nodes/remote/imageReferenceSheet.js.map +1 -0
  231. package/dist/engine/nodes/remote/imageSearch.d.ts +18 -0
  232. package/dist/engine/nodes/remote/imageSearch.d.ts.map +1 -0
  233. package/dist/engine/nodes/remote/imageSearch.js +22 -0
  234. package/dist/engine/nodes/remote/imageSearch.js.map +1 -0
  235. package/dist/engine/nodes/remote/imageSelect.d.ts +39 -0
  236. package/dist/engine/nodes/remote/imageSelect.d.ts.map +1 -0
  237. package/dist/engine/nodes/remote/imageSelect.js +45 -0
  238. package/dist/engine/nodes/remote/imageSelect.js.map +1 -0
  239. package/dist/engine/nodes/remote/music.d.ts +45 -0
  240. package/dist/engine/nodes/remote/music.d.ts.map +1 -0
  241. package/dist/engine/nodes/remote/music.js +73 -0
  242. package/dist/engine/nodes/remote/music.js.map +1 -0
  243. package/dist/engine/nodes/remote/soundEffect.d.ts +21 -0
  244. package/dist/engine/nodes/remote/soundEffect.d.ts.map +1 -0
  245. package/dist/engine/nodes/remote/soundEffect.js +41 -0
  246. package/dist/engine/nodes/remote/soundEffect.js.map +1 -0
  247. package/dist/engine/nodes/remote/textGenerate.d.ts +21 -0
  248. package/dist/engine/nodes/remote/textGenerate.d.ts.map +1 -0
  249. package/dist/engine/nodes/remote/textGenerate.js +27 -0
  250. package/dist/engine/nodes/remote/textGenerate.js.map +1 -0
  251. package/dist/engine/nodes/remote/tts.d.ts +45 -0
  252. package/dist/engine/nodes/remote/tts.d.ts.map +1 -0
  253. package/dist/engine/nodes/remote/tts.js +66 -0
  254. package/dist/engine/nodes/remote/tts.js.map +1 -0
  255. package/dist/engine/nodes/remote/video.d.ts +58 -0
  256. package/dist/engine/nodes/remote/video.d.ts.map +1 -0
  257. package/dist/engine/nodes/remote/video.js +44 -0
  258. package/dist/engine/nodes/remote/video.js.map +1 -0
  259. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts +30 -0
  260. package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts.map +1 -0
  261. package/dist/engine/nodes/remote/videoBackgroundRemove.js +29 -0
  262. package/dist/engine/nodes/remote/videoBackgroundRemove.js.map +1 -0
  263. package/dist/engine/nodes/remote/videoDeconstruct.d.ts +61 -0
  264. package/dist/engine/nodes/remote/videoDeconstruct.d.ts.map +1 -0
  265. package/dist/engine/nodes/remote/videoDeconstruct.js +40 -0
  266. package/dist/engine/nodes/remote/videoDeconstruct.js.map +1 -0
  267. package/dist/engine/nodes/remote/videoLipsync.d.ts +37 -0
  268. package/dist/engine/nodes/remote/videoLipsync.d.ts.map +1 -0
  269. package/dist/engine/nodes/remote/videoLipsync.js +26 -0
  270. package/dist/engine/nodes/remote/videoLipsync.js.map +1 -0
  271. package/dist/engine/nodes/remote/videoTranscribe.d.ts +116 -0
  272. package/dist/engine/nodes/remote/videoTranscribe.d.ts.map +1 -0
  273. package/dist/engine/nodes/remote/videoTranscribe.js +123 -0
  274. package/dist/engine/nodes/remote/videoTranscribe.js.map +1 -0
  275. package/dist/engine/nodes/remote/voiceSelect.d.ts +28 -0
  276. package/dist/engine/nodes/remote/voiceSelect.d.ts.map +1 -0
  277. package/dist/engine/nodes/remote/voiceSelect.js +25 -0
  278. package/dist/engine/nodes/remote/voiceSelect.js.map +1 -0
  279. package/dist/engine/scaffold/staticAd.d.ts +44 -0
  280. package/dist/engine/scaffold/staticAd.d.ts.map +1 -0
  281. package/dist/engine/scaffold/staticAd.js +243 -0
  282. package/dist/engine/scaffold/staticAd.js.map +1 -0
  283. package/dist/engine/scaffold/video.d.ts +56 -0
  284. package/dist/engine/scaffold/video.d.ts.map +1 -0
  285. package/dist/engine/scaffold/video.js +709 -0
  286. package/dist/engine/scaffold/video.js.map +1 -0
  287. package/dist/engine/schema/canvas.d.ts +41 -0
  288. package/dist/engine/schema/canvas.d.ts.map +1 -0
  289. package/dist/engine/schema/canvas.js +67 -0
  290. package/dist/engine/schema/canvas.js.map +1 -0
  291. package/dist/engine/schema/catalog.d.ts +25 -0
  292. package/dist/engine/schema/catalog.d.ts.map +1 -0
  293. package/dist/engine/schema/catalog.js +48 -0
  294. package/dist/engine/schema/catalog.js.map +1 -0
  295. package/dist/engine/schema/primitives.d.ts +6 -0
  296. package/dist/engine/schema/primitives.d.ts.map +1 -0
  297. package/dist/engine/schema/primitives.js +4 -0
  298. package/dist/engine/schema/primitives.js.map +1 -0
  299. package/dist/engine/schema/prompts.d.ts +4 -0
  300. package/dist/engine/schema/prompts.d.ts.map +1 -0
  301. package/dist/engine/schema/prompts.js +23 -0
  302. package/dist/engine/schema/prompts.js.map +1 -0
  303. package/dist/engine/schema/refs.d.ts +113 -0
  304. package/dist/engine/schema/refs.d.ts.map +1 -0
  305. package/dist/engine/schema/refs.js +35 -0
  306. package/dist/engine/schema/refs.js.map +1 -0
  307. package/dist/engine/storage/asset-store.d.ts +48 -0
  308. package/dist/engine/storage/asset-store.d.ts.map +1 -0
  309. package/dist/engine/storage/asset-store.js +166 -0
  310. package/dist/engine/storage/asset-store.js.map +1 -0
  311. package/dist/engine/storage/cache-store.d.ts +21 -0
  312. package/dist/engine/storage/cache-store.d.ts.map +1 -0
  313. package/dist/engine/storage/cache-store.js +31 -0
  314. package/dist/engine/storage/cache-store.js.map +1 -0
  315. package/dist/engine/storage/output-writer.d.ts +18 -0
  316. package/dist/engine/storage/output-writer.d.ts.map +1 -0
  317. package/dist/engine/storage/output-writer.js +52 -0
  318. package/dist/engine/storage/output-writer.js.map +1 -0
  319. package/dist/engine/storage/sha256.d.ts +2 -0
  320. package/dist/engine/storage/sha256.d.ts.map +1 -0
  321. package/dist/engine/storage/sha256.js +7 -0
  322. package/dist/engine/storage/sha256.js.map +1 -0
  323. package/package.json +15 -3
@@ -0,0 +1,198 @@
1
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { createRequire } from "node:module";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { z } from "zod";
6
+ import { defineNode } from "../../engine/define.js";
7
+ import { NodeExecutionError } from "../../engine/errors.js";
8
+ import { FontRef, ImageRef } from "../../schema/refs.js";
9
+ import { extForMime } from "../../storage/asset-store.js";
10
+ import { uploadAndIngest } from "../ingest.js";
11
+ import { stageAsset } from "./lib/assets.js";
12
+ const require_ = createRequire(import.meta.url);
13
+ export const DEFAULT_SPECIMEN = [
14
+ "The quick brown fox jumps over the lazy dog",
15
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
16
+ "abcdefghijklmnopqrstuvwxyz",
17
+ "0123456789 !?&@#$%().,:;'\"-",
18
+ ].join("\n");
19
+ const FontSpecimenParams = z
20
+ .object({
21
+ text: z.string().min(1).max(2000).optional().default(DEFAULT_SPECIMEN),
22
+ font_size: z.number().int().min(8).max(512).optional().default(72),
23
+ padding: z.number().int().min(0).max(512).optional().default(64),
24
+ line_height: z.number().min(0.8).max(3).optional().default(1.35),
25
+ max_width: z.number().int().min(256).max(4096).optional(),
26
+ })
27
+ .strict();
28
+ // `.loose()` so the exact copy that will appear in the ad can be wired in from
29
+ // an upstream node (e.g. text_generate) and referenced via `{{slot}}` in the
30
+ // `text` param — render the specimen on the real headline, not placeholder text.
31
+ const FontSpecimenInputs = z.object({ font: FontRef }).loose();
32
+ const FontSpecimenOutputs = z.object({ image: ImageRef }).strict();
33
+ // Retina export, consistent with hyperframe_snapshot.
34
+ const DEVICE_SCALE_FACTOR = 2;
35
+ const PAGE_TIMEOUT_MS = 30_000;
36
+ function escapeHtml(text) {
37
+ return text
38
+ .replaceAll("&", "&")
39
+ .replaceAll("<", "&lt;")
40
+ .replaceAll(">", "&gt;")
41
+ .replaceAll('"', "&quot;")
42
+ .replaceAll("'", "&#39;");
43
+ }
44
+ /**
45
+ * Self-contained specimen page: the staged font is the ONLY family declared,
46
+ * so a load failure is detectable instead of silently falling back to a
47
+ * system font (which would defeat the node's purpose).
48
+ */
49
+ function buildSpecimenHtml(params, fontFilename) {
50
+ const widthRule = params.max_width === undefined ? "width: max-content;" : `max-width: ${params.max_width}px;`;
51
+ return `<!doctype html>
52
+ <html>
53
+ <head>
54
+ <meta charset="utf-8">
55
+ <style>
56
+ @font-face {
57
+ font-family: 'SpecimenFont';
58
+ src: url('${fontFilename}');
59
+ }
60
+ html, body { margin: 0; background: #fff; }
61
+ #specimen {
62
+ font-family: 'SpecimenFont';
63
+ color: #000;
64
+ background: #fff;
65
+ font-size: ${params.font_size}px;
66
+ line-height: ${params.line_height};
67
+ padding: ${params.padding}px;
68
+ white-space: pre-wrap;
69
+ overflow-wrap: break-word;
70
+ ${widthRule}
71
+ }
72
+ </style>
73
+ </head>
74
+ <body><div id="specimen">${escapeHtml(params.text)}</div></body>
75
+ </html>
76
+ `;
77
+ }
78
+ export const fontSpecimenNode = defineNode({
79
+ id: "font_specimen",
80
+ version: "1.1.0",
81
+ category: "image",
82
+ location: "local",
83
+ summary: "Render specimen text in a given font file to a PNG — black text on a white background — via headless Chromium. " +
84
+ "Produces a typeface reference image an image model can replicate.",
85
+ when_to_use: "Use when a generated image must contain text in a specific brand font: wire `image` into `image_generate`'s `reference` input so the model copies the typeface. " +
86
+ 'Input is a `font` asset (ttf/otf/woff/woff2) — get one via `ingest` with `expect: "font"`. ' +
87
+ "Default specimen covers a pangram, both alphabets, digits and punctuation; override with `params.text` (e.g. the exact headline to render).",
88
+ inputs: FontSpecimenInputs,
89
+ params: FontSpecimenParams,
90
+ outputs: FontSpecimenOutputs,
91
+ outputKinds: { image: "image" },
92
+ cost: () => ({ credits: 0, seconds_estimate: 5 }),
93
+ async execute({ inputs, params, ctx }) {
94
+ const tmp = await mkdtemp(path.join(tmpdir(), "font-specimen-"));
95
+ try {
96
+ const fontFilename = `font.${extForMime(inputs.font.mime)}`;
97
+ await stageAsset(inputs.font, tmp, fontFilename);
98
+ const entryPath = path.join(tmp, "index.html");
99
+ await writeFile(entryPath, buildSpecimenHtml(params, fontFilename), "utf-8");
100
+ ctx.log(`rendering specimen (${params.font_size}px, ${params.text.split("\n").length} lines)`);
101
+ const pwSpecifier = ["play", "wright"].join("");
102
+ const playwright = require_(pwSpecifier);
103
+ const browser = await playwright.chromium.launch({ headless: true });
104
+ try {
105
+ const context = await browser.newContext({
106
+ viewport: { width: 1280, height: 720 },
107
+ deviceScaleFactor: DEVICE_SCALE_FACTOR,
108
+ });
109
+ const page = await context.newPage();
110
+ await page.goto(`file://${entryPath}`, { waitUntil: "load", timeout: PAGE_TIMEOUT_MS });
111
+ // Fail loudly when Chromium can't parse the font — the page declares
112
+ // no fallback family, but a broken file would otherwise still render
113
+ // with the browser's last-resort font and silently lie downstream.
114
+ const loaded = await page
115
+ .evaluate(async () => {
116
+ const faces = await document.fonts.load("16px 'SpecimenFont'");
117
+ await document.fonts.ready;
118
+ return faces.length;
119
+ })
120
+ .catch(() => 0);
121
+ if (loaded === 0) {
122
+ throw new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
123
+ kind: "local",
124
+ cause: new Error(`font_specimen: Chromium could not load the font (${inputs.font.mime}) — is the file a valid ttf/otf/woff/woff2?`),
125
+ });
126
+ }
127
+ // A font can load yet cover none of the specimen's characters (e.g. a
128
+ // script-subset woff2 with no Latin glyphs) — Chromium then falls back
129
+ // per character and the specimen would silently show a system font.
130
+ // Detection: a covered char measures identically under both fallback
131
+ // stacks (the font itself renders it); an uncovered char differs
132
+ // (monospace vs serif fallback metrics diverge).
133
+ const { covered, missing } = await page.evaluate((text) => {
134
+ const chars = [...new Set(text.replace(/\s/g, ""))];
135
+ const c = document.createElement("canvas").getContext("2d");
136
+ if (!c)
137
+ return { covered: chars.length, missing: [] };
138
+ const missingChars = [];
139
+ for (const ch of chars) {
140
+ c.font = "64px 'SpecimenFont', monospace";
141
+ const a = c.measureText(ch).width;
142
+ c.font = "64px 'SpecimenFont', serif";
143
+ const b = c.measureText(ch).width;
144
+ if (a !== b)
145
+ missingChars.push(ch);
146
+ }
147
+ return { covered: chars.length - missingChars.length, missing: missingChars };
148
+ }, params.text);
149
+ if (covered === 0) {
150
+ throw new NodeExecutionError(ctx.nodeId, ctx.nodeType, {
151
+ kind: "local",
152
+ cause: new Error("font_specimen: the font loaded but provides no glyphs for the specimen text — is it a subset for another script? Use a full (e.g. latin) build of the font, or change params.text."),
153
+ });
154
+ }
155
+ if (missing.length > 0) {
156
+ ctx.log(`warning: font has no glyphs for ${missing.length} character(s): ${missing.join(" ")}`);
157
+ }
158
+ const specimen = page.locator("#specimen");
159
+ const box = await specimen.boundingBox();
160
+ const bytes = await specimen.screenshot({ type: "png", timeout: PAGE_TIMEOUT_MS });
161
+ ctx.log(`captured ${bytes.length} bytes`);
162
+ const metadata = {
163
+ font_sha256: inputs.font.sha256,
164
+ font_mime: inputs.font.mime,
165
+ };
166
+ if (box) {
167
+ metadata.width = Math.round(box.width * DEVICE_SCALE_FACTOR);
168
+ metadata.height = Math.round(box.height * DEVICE_SCALE_FACTOR);
169
+ }
170
+ // Upload to R2 (not just the local store): downstream remote nodes
171
+ // (image_generate reference) receive only `url` — see stripLocalRefs.
172
+ const ref = await uploadAndIngest({
173
+ bytes: Buffer.from(bytes),
174
+ kind: "image",
175
+ mime: "image/png",
176
+ metadata,
177
+ ctx,
178
+ });
179
+ return { image: ref };
180
+ }
181
+ finally {
182
+ await browser.close();
183
+ }
184
+ }
185
+ finally {
186
+ await rm(tmp, { recursive: true, force: true }).catch((cleanupErr) => {
187
+ ctx.log(`warning: tmp cleanup failed (${cleanupErr.message})`);
188
+ });
189
+ }
190
+ },
191
+ });
192
+ // Exported for unit tests.
193
+ export const _internal = {
194
+ FontSpecimenParams,
195
+ buildSpecimenHtml,
196
+ escapeHtml,
197
+ };
198
+ //# sourceMappingURL=fontSpecimen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fontSpecimen.js","sourceRoot":"","sources":["../../../../src/engine/nodes/local/fontSpecimen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEhD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,6CAA6C;IAC7C,4BAA4B;IAC5B,4BAA4B;IAC5B,8BAA8B;CAC/B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,kBAAkB,GAAG,CAAC;KACzB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAClE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAChE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC;KACD,MAAM,EAAE,CAAC;AAIZ,+EAA+E;AAC/E,6EAA6E;AAC7E,iFAAiF;AACjF,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAC/D,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAEnE,sDAAsD;AACtD,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI;SACR,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC;SACvB,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC;SACzB,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,YAAoB;IAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,SAAS,KAAK,CAAC;IAC/G,OAAO;;;;;;;gBAOO,YAAY;;;;;;;iBAOX,MAAM,CAAC,SAAS;mBACd,MAAM,CAAC,WAAW;eACtB,MAAM,CAAC,OAAO;;;MAGvB,SAAS;;;;2BAIY,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC;;CAEjD,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;IACzC,EAAE,EAAE,eAAe;IACnB,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,OAAO;IACjB,QAAQ,EAAE,OAAO;IACjB,OAAO,EACL,iHAAiH;QACjH,mEAAmE;IACrE,WAAW,EACT,kKAAkK;QAClK,6FAA6F;QAC7F,6IAA6I;IAC/I,MAAM,EAAE,kBAAkB;IAC1B,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;IAC/B,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IAEjD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE;QACnC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,QAAQ,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5D,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;YAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;YAC/C,MAAM,SAAS,CAAC,SAAS,EAAE,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;YAE7E,GAAG,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,SAAS,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC;YAE/F,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAgC,CAAC;YACxE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;oBACvC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;oBACtC,iBAAiB,EAAE,mBAAmB;iBACvC,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;gBAExF,qEAAqE;gBACrE,qEAAqE;gBACrE,mEAAmE;gBACnE,MAAM,MAAM,GAAG,MAAM,IAAI;qBACtB,QAAQ,CAAC,KAAK,IAAI,EAAE;oBACnB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBAC/D,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;oBAC3B,OAAO,KAAK,CAAC,MAAM,CAAC;gBACtB,CAAC,CAAC;qBACD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;gBAClB,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjB,MAAM,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE;wBACrD,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,IAAI,KAAK,CACd,oDAAoD,MAAM,CAAC,IAAI,CAAC,IAAI,6CAA6C,CAClH;qBACF,CAAC,CAAC;gBACL,CAAC;gBAED,sEAAsE;gBACtE,uEAAuE;gBACvE,oEAAoE;gBACpE,qEAAqE;gBACrE,iEAAiE;gBACjE,iDAAiD;gBACjD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAY,EAAE,EAAE;oBAChE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;oBACpD,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBAC5D,IAAI,CAAC,CAAC;wBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAc,EAAE,CAAC;oBAClE,MAAM,YAAY,GAAa,EAAE,CAAC;oBAClC,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;wBACvB,CAAC,CAAC,IAAI,GAAG,gCAAgC,CAAC;wBAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;wBAClC,CAAC,CAAC,IAAI,GAAG,4BAA4B,CAAC;wBACtC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;wBAClC,IAAI,CAAC,KAAK,CAAC;4BAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACrC,CAAC;oBACD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;gBAChF,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChB,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;oBAClB,MAAM,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE;wBACrD,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,IAAI,KAAK,CACd,oLAAoL,CACrL;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,GAAG,CAAC,GAAG,CAAC,mCAAmC,OAAO,CAAC,MAAM,kBAAkB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClG,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAC3C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;gBACnF,GAAG,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAE1C,MAAM,QAAQ,GAA4B;oBACxC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;oBAC/B,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;iBAC5B,CAAC;gBACF,IAAI,GAAG,EAAE,CAAC;oBACR,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,mBAAmB,CAAC,CAAC;oBAC7D,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC;gBACjE,CAAC;gBAED,mEAAmE;gBACnE,sEAAsE;gBACtE,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;oBAChC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;oBACzB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,WAAW;oBACjB,QAAQ;oBACR,GAAG;iBACJ,CAAC,CAAC;gBACH,OAAO,EAAE,KAAK,EAAE,GAA+B,EAAE,CAAC;YACpD,CAAC;oBAAS,CAAC;gBACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE;gBACnE,GAAG,CAAC,GAAG,CAAC,gCAAiC,UAAoB,CAAC,OAAO,GAAG,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH,2BAA2B;AAC3B,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,kBAAkB;IAClB,iBAAiB;IACjB,UAAU;CACX,CAAC"}
@@ -0,0 +1,116 @@
1
+ export declare const hyperframeSnapshotNode: import("../../engine/define.ts").NodeDefinition<Record<string, {
2
+ sha256: string;
3
+ mime: string;
4
+ kind: "image";
5
+ url?: string | undefined;
6
+ path?: string | undefined;
7
+ metadata?: Record<string, unknown> | undefined;
8
+ width?: number | undefined;
9
+ height?: number | undefined;
10
+ } | {
11
+ sha256: string;
12
+ mime: string;
13
+ kind: "video";
14
+ url?: string | undefined;
15
+ path?: string | undefined;
16
+ metadata?: Record<string, unknown> | undefined;
17
+ width?: number | undefined;
18
+ height?: number | undefined;
19
+ duration_ms?: number | undefined;
20
+ } | {
21
+ sha256: string;
22
+ mime: string;
23
+ kind: "audio";
24
+ url?: string | undefined;
25
+ path?: string | undefined;
26
+ metadata?: Record<string, unknown> | undefined;
27
+ duration_ms?: number | undefined;
28
+ } | {
29
+ sha256: string;
30
+ mime: string;
31
+ kind: "json";
32
+ url?: string | undefined;
33
+ path?: string | undefined;
34
+ metadata?: Record<string, unknown> | undefined;
35
+ } | {
36
+ sha256: string;
37
+ mime: string;
38
+ kind: "text";
39
+ url?: string | undefined;
40
+ path?: string | undefined;
41
+ metadata?: Record<string, unknown> | undefined;
42
+ } | {
43
+ sha256: string;
44
+ mime: string;
45
+ kind: "font";
46
+ url?: string | undefined;
47
+ path?: string | undefined;
48
+ metadata?: Record<string, unknown> | undefined;
49
+ }>, {
50
+ [x: string]: unknown;
51
+ composition: string;
52
+ wait_for: {
53
+ kind: "auto";
54
+ } | {
55
+ kind: "selector";
56
+ value: string;
57
+ } | {
58
+ kind: "function";
59
+ value: string;
60
+ } | {
61
+ kind: "timeout";
62
+ ms: number;
63
+ };
64
+ timeout_ms: number;
65
+ }, {
66
+ image: {
67
+ sha256: string;
68
+ mime: string;
69
+ kind: "image";
70
+ url?: string | undefined;
71
+ path?: string | undefined;
72
+ metadata?: Record<string, unknown> | undefined;
73
+ width?: number | undefined;
74
+ height?: number | undefined;
75
+ } | {
76
+ sha256: string;
77
+ mime: string;
78
+ kind: "video";
79
+ url?: string | undefined;
80
+ path?: string | undefined;
81
+ metadata?: Record<string, unknown> | undefined;
82
+ width?: number | undefined;
83
+ height?: number | undefined;
84
+ duration_ms?: number | undefined;
85
+ } | {
86
+ sha256: string;
87
+ mime: string;
88
+ kind: "audio";
89
+ url?: string | undefined;
90
+ path?: string | undefined;
91
+ metadata?: Record<string, unknown> | undefined;
92
+ duration_ms?: number | undefined;
93
+ } | {
94
+ sha256: string;
95
+ mime: string;
96
+ kind: "json";
97
+ url?: string | undefined;
98
+ path?: string | undefined;
99
+ metadata?: Record<string, unknown> | undefined;
100
+ } | {
101
+ sha256: string;
102
+ mime: string;
103
+ kind: "text";
104
+ url?: string | undefined;
105
+ path?: string | undefined;
106
+ metadata?: Record<string, unknown> | undefined;
107
+ } | {
108
+ sha256: string;
109
+ mime: string;
110
+ kind: "font";
111
+ url?: string | undefined;
112
+ path?: string | undefined;
113
+ metadata?: Record<string, unknown> | undefined;
114
+ };
115
+ }>;
116
+ //# sourceMappingURL=hyperframe-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hyperframe-snapshot.d.ts","sourceRoot":"","sources":["../../../../src/engine/nodes/local/hyperframe-snapshot.ts"],"names":[],"mappings":"AAyDA,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyFjC,CAAC"}
@@ -0,0 +1,230 @@
1
+ import { execFile } from "node:child_process";
2
+ import { copyFile, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { createRequire } from "node:module";
4
+ import { 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 { assertInputsMatchMeta, resolveCompositionDir, validateCompositionParams } from "./hyperframe.js";
12
+ import { isAssetRefLike, refToUrl, stageAsset } from "./lib/assets.js";
13
+ import { mapKnownHyperframesError } from "./lib/hyperframe-errors.js";
14
+ import { substituteVariables } from "./lib/templating.js";
15
+ const _execFileAsync = promisify(execFile);
16
+ const require_ = createRequire(import.meta.url);
17
+ const WaitForSpec = z.discriminatedUnion("kind", [
18
+ z.object({ kind: z.literal("auto") }),
19
+ z.object({ kind: z.literal("selector"), value: z.string().min(1) }),
20
+ z.object({ kind: z.literal("function"), value: z.string().min(1) }),
21
+ z.object({ kind: z.literal("timeout"), ms: z.number().int().min(0).max(60_000) }),
22
+ ]);
23
+ // Output is always rendered at the composition's declared width/height at 2x
24
+ // device-scale (retina) for ad delivery. No knobs for full-page or transparent
25
+ // background — composition controls the canvas size and background.
26
+ const HyperframeSnapshotParams = z
27
+ .object({
28
+ composition: z.string().min(1),
29
+ wait_for: WaitForSpec.optional().default({ kind: "auto" }),
30
+ timeout_ms: z.number().int().positive().optional().default(60_000),
31
+ })
32
+ .catchall(z.unknown());
33
+ const HyperframeSnapshotInputs = z.record(z.string(), z.custom()).optional().default({});
34
+ const HyperframeSnapshotOutputs = z
35
+ .object({
36
+ image: z.custom(),
37
+ })
38
+ .strict();
39
+ const NODE_OWNED_PARAM_KEYS = new Set(["composition", "wait_for", "timeout_ms"]);
40
+ // Retina export — fixed for ad-creative delivery.
41
+ const DEVICE_SCALE_FACTOR = 2;
42
+ export const hyperframeSnapshotNode = defineNode({
43
+ id: "hyperframe_snapshot",
44
+ version: "4.0.0",
45
+ category: "image",
46
+ location: "local",
47
+ summary: "Render an HTML/CSS composition to a static PNG via headless Chromium at 2x device-scale (retina). Same composition model as `hyperframe_render` — point `params.composition` at a directory containing `index.html` + `meta.json`.",
48
+ when_to_use: "Use for static visuals composed from HTML/CSS: UI mockups, branded social posts, text overlays, multi-image grids. " +
49
+ "Point `params.composition` at a directory containing `index.html` + `meta.json`. " +
50
+ "Inputs are keyed by `meta.json.inputs`. " +
51
+ "Output size: composition `meta.json` width/height × 2 (retina). " +
52
+ '`wait_for` defaults to `"auto"` which waits for page `load` + all `<img>` decoded + web fonts ready.',
53
+ inputs: HyperframeSnapshotInputs,
54
+ params: HyperframeSnapshotParams,
55
+ outputs: HyperframeSnapshotOutputs,
56
+ cost: () => ({ credits: 0, seconds_estimate: 3 }),
57
+ validateExtra: ({ rawParams }) => validateCompositionParams(rawParams),
58
+ cacheKeyExtras: async ({ params }) => {
59
+ const out = {};
60
+ const composition = params.composition;
61
+ if (typeof composition !== "string")
62
+ return out;
63
+ const dir = await resolveCompositionDir(composition).catch(() => null);
64
+ if (!dir)
65
+ return out;
66
+ out.composition_content_sha = await hashCompositionDir(dir);
67
+ return out;
68
+ },
69
+ async execute({ inputs, params, ctx }) {
70
+ const compositionDir = await resolveCompositionDir(params.composition);
71
+ const meta = await loadCompositionMeta(compositionDir);
72
+ const compositionParams = validateAndParseDynamicParams(meta, params);
73
+ const tmp = await mkdtemp(path.join(tmpdir(), "hf-snap-"));
74
+ try {
75
+ await copyComposition(compositionDir, tmp);
76
+ await vendorGsap(tmp, ctx);
77
+ await stageInputs(tmp, inputs, meta, ctx);
78
+ const substitutionValues = await buildSubstitutionValues(compositionParams, meta);
79
+ await substituteCompositionFiles(tmp, substitutionValues);
80
+ const entryPath = path.join(tmp, "index.html");
81
+ const entryUrl = `file://${entryPath}`;
82
+ ctx.log(`snapshotting ${meta.width}x${meta.height}@${DEVICE_SCALE_FACTOR}x wait=${params.wait_for.kind}`);
83
+ const pwSpecifier = ["play", "wright"].join("");
84
+ const playwright = require_(pwSpecifier);
85
+ const { chromium } = playwright;
86
+ const browser = await chromium.launch({ headless: true });
87
+ try {
88
+ const context = await browser.newContext({
89
+ viewport: { width: meta.width, height: meta.height },
90
+ deviceScaleFactor: DEVICE_SCALE_FACTOR,
91
+ });
92
+ const page = await context.newPage();
93
+ await page.goto(entryUrl, { waitUntil: "load", timeout: params.timeout_ms });
94
+ await waitForReady(page, params.wait_for, params.timeout_ms);
95
+ const bytes = await page.screenshot({ type: "png" });
96
+ ctx.log(`captured ${bytes.length} bytes`);
97
+ const ref = await ctx.assets.ingestBytes({
98
+ bytes: Buffer.from(bytes),
99
+ kind: "image",
100
+ mime: "image/png",
101
+ metadata: {
102
+ width: meta.width * DEVICE_SCALE_FACTOR,
103
+ height: meta.height * DEVICE_SCALE_FACTOR,
104
+ },
105
+ });
106
+ return { image: ref };
107
+ }
108
+ finally {
109
+ await browser.close();
110
+ }
111
+ }
112
+ catch (e) {
113
+ const detail = e.message;
114
+ const friendly = mapKnownHyperframesError(detail);
115
+ if (friendly)
116
+ throw new Error(`hyperframe_snapshot: ${friendly}`);
117
+ throw e;
118
+ }
119
+ finally {
120
+ await rm(tmp, { recursive: true, force: true }).catch((cleanupErr) => {
121
+ ctx.log(`warning: tmp cleanup failed (${cleanupErr.message})`);
122
+ });
123
+ }
124
+ },
125
+ });
126
+ function validateAndParseDynamicParams(meta, params) {
127
+ const dynamic = {};
128
+ for (const [k, v] of Object.entries(params)) {
129
+ if (NODE_OWNED_PARAM_KEYS.has(k))
130
+ continue;
131
+ dynamic[k] = v;
132
+ }
133
+ const schema = buildParamsSchema(meta);
134
+ const parsed = schema.safeParse(dynamic);
135
+ if (!parsed.success) {
136
+ const summary = parsed.error.issues.map((i) => `params.${i.path.join(".")}: ${i.message}`).join("; ");
137
+ throw new Error(`hyperframe_snapshot: composition param validation failed — ${summary}`);
138
+ }
139
+ return parsed.data;
140
+ }
141
+ async function copyComposition(srcDir, destDir) {
142
+ const { cp } = await import("node:fs/promises");
143
+ await cp(srcDir, destDir, {
144
+ recursive: true,
145
+ filter: (src) => {
146
+ const name = path.basename(src);
147
+ if (name === ".cache" || name === "node_modules" || name === ".git")
148
+ return false;
149
+ return true;
150
+ },
151
+ });
152
+ }
153
+ async function vendorGsap(tmp, ctx) {
154
+ try {
155
+ const gsapMin = require_.resolve("gsap/dist/gsap.min.js");
156
+ await copyFile(gsapMin, path.join(tmp, "gsap.min.js"));
157
+ }
158
+ catch (e) {
159
+ ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
160
+ }
161
+ }
162
+ async function stageInputs(tmp, inputs, meta, ctx) {
163
+ assertInputsMatchMeta(inputs, meta, "hyperframe_snapshot");
164
+ for (const [key, ref] of Object.entries(inputs ?? {})) {
165
+ const spec = meta.inputs[key];
166
+ if (!spec)
167
+ continue;
168
+ const filename = spec.staged_as ?? defaultFilenameForInput(key, spec.kind);
169
+ await stageAsset(ref, tmp, filename);
170
+ ctx.log(`staged ${spec.kind} → ${filename}`);
171
+ }
172
+ }
173
+ async function buildSubstitutionValues(compositionParams, meta) {
174
+ const out = {};
175
+ for (const [name, value] of Object.entries(compositionParams)) {
176
+ const spec = meta.params[name];
177
+ if (spec?.kind === "image") {
178
+ out[name] = await coerceImageParam(value);
179
+ continue;
180
+ }
181
+ out[name] = value;
182
+ }
183
+ // Snapshots have no real duration; expose a sensible value for compositions
184
+ // shared with hyperframe_render that reference {{duration}}.
185
+ out.duration = meta.default_duration.toFixed(3);
186
+ return out;
187
+ }
188
+ function coerceImageParam(value) {
189
+ if (typeof value === "string")
190
+ return Promise.resolve(value);
191
+ if (isAssetRefLike(value))
192
+ return refToUrl(value);
193
+ throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
194
+ }
195
+ async function substituteCompositionFiles(tmp, values) {
196
+ const entryPath = path.join(tmp, "index.html");
197
+ const original = await readFile(entryPath, "utf-8");
198
+ const { output, missing } = substituteVariables(original, values);
199
+ if (missing.length > 0) {
200
+ throw new Error(`hyperframe_snapshot: composition references undefined variables: ${missing.map((m) => `{{${m}}}`).join(", ")}.`);
201
+ }
202
+ await writeFile(entryPath, output, "utf-8");
203
+ }
204
+ async function waitForReady(page, waitFor, timeoutMs) {
205
+ switch (waitFor.kind) {
206
+ case "auto":
207
+ await page.evaluate(async () => {
208
+ const imgs = Array.from(document.images);
209
+ await Promise.all(imgs.map((img) => img.complete && img.naturalWidth > 0 ? Promise.resolve() : img.decode().catch(() => undefined)));
210
+ if (document.fonts && typeof document.fonts.ready?.then === "function") {
211
+ await document.fonts.ready;
212
+ }
213
+ });
214
+ return;
215
+ case "selector":
216
+ await page.waitForSelector(waitFor.value, { timeout: timeoutMs });
217
+ return;
218
+ case "function":
219
+ await page.waitForFunction(waitFor.value, undefined, { timeout: timeoutMs });
220
+ return;
221
+ case "timeout":
222
+ await page.waitForTimeout(waitFor.ms);
223
+ return;
224
+ default: {
225
+ const _exhaustive = waitFor;
226
+ throw new Error(`hyperframe_snapshot: unknown wait_for kind ${_exhaustive.kind}`);
227
+ }
228
+ }
229
+ }
230
+ //# sourceMappingURL=hyperframe-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hyperframe-snapshot.js","sourceRoot":"","sources":["../../../../src/engine/nodes/local/hyperframe-snapshot.ts"],"names":[],"mappings":"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"}