frameyard 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/CHANGELOG.md +164 -7
  2. package/GLOSSARY.md +152 -18
  3. package/README.md +328 -285
  4. package/dist/assets/integrations.d.ts +8 -4
  5. package/dist/assets/integrations.d.ts.map +1 -1
  6. package/dist/assets/integrations.js +8 -4
  7. package/dist/assets/integrations.js.map +1 -1
  8. package/dist/assets/provenance.d.ts +2 -2
  9. package/dist/assets/provenance.d.ts.map +1 -1
  10. package/dist/assets/provenance.js +5 -3
  11. package/dist/assets/provenance.js.map +1 -1
  12. package/dist/assets/tts-supertonic.d.ts +28 -0
  13. package/dist/assets/tts-supertonic.d.ts.map +1 -0
  14. package/dist/assets/tts-supertonic.js +156 -0
  15. package/dist/assets/tts-supertonic.js.map +1 -0
  16. package/dist/assets/tts.d.ts +18 -6
  17. package/dist/assets/tts.d.ts.map +1 -1
  18. package/dist/assets/tts.js +219 -97
  19. package/dist/assets/tts.js.map +1 -1
  20. package/dist/cli.js +1705 -106
  21. package/dist/cli.js.map +1 -1
  22. package/dist/composition/descriptor.d.ts +17 -3
  23. package/dist/composition/descriptor.d.ts.map +1 -1
  24. package/dist/composition/descriptor.js +51 -28
  25. package/dist/composition/descriptor.js.map +1 -1
  26. package/dist/composition/format.d.ts +12 -0
  27. package/dist/composition/format.d.ts.map +1 -0
  28. package/dist/composition/format.js +28 -0
  29. package/dist/composition/format.js.map +1 -0
  30. package/dist/composition/index.d.ts +2 -1
  31. package/dist/composition/index.d.ts.map +1 -1
  32. package/dist/composition/index.js +1 -0
  33. package/dist/composition/index.js.map +1 -1
  34. package/dist/context.d.ts +82 -0
  35. package/dist/context.d.ts.map +1 -0
  36. package/dist/context.js +277 -0
  37. package/dist/context.js.map +1 -0
  38. package/dist/contracts.d.ts +80 -6
  39. package/dist/contracts.d.ts.map +1 -1
  40. package/dist/contracts.js +3 -0
  41. package/dist/contracts.js.map +1 -1
  42. package/dist/doctor.d.ts +14 -1
  43. package/dist/doctor.d.ts.map +1 -1
  44. package/dist/doctor.js +166 -7
  45. package/dist/doctor.js.map +1 -1
  46. package/dist/errors.d.ts +1 -1
  47. package/dist/errors.d.ts.map +1 -1
  48. package/dist/errors.js.map +1 -1
  49. package/dist/fonts/add.d.ts +41 -0
  50. package/dist/fonts/add.d.ts.map +1 -0
  51. package/dist/fonts/add.js +259 -0
  52. package/dist/fonts/add.js.map +1 -0
  53. package/dist/fonts/binary.d.ts +4 -0
  54. package/dist/fonts/binary.d.ts.map +1 -0
  55. package/dist/fonts/binary.js +21 -0
  56. package/dist/fonts/binary.js.map +1 -0
  57. package/dist/fonts/css.d.ts +4 -0
  58. package/dist/fonts/css.d.ts.map +1 -0
  59. package/dist/fonts/css.js +50 -0
  60. package/dist/fonts/css.js.map +1 -0
  61. package/dist/fonts/fontsource.d.ts +107 -0
  62. package/dist/fonts/fontsource.d.ts.map +1 -0
  63. package/dist/fonts/fontsource.js +565 -0
  64. package/dist/fonts/fontsource.js.map +1 -0
  65. package/dist/fonts/index.d.ts +11 -0
  66. package/dist/fonts/index.d.ts.map +1 -0
  67. package/dist/fonts/index.js +11 -0
  68. package/dist/fonts/index.js.map +1 -0
  69. package/dist/fonts/install.d.ts +24 -0
  70. package/dist/fonts/install.d.ts.map +1 -0
  71. package/dist/fonts/install.js +145 -0
  72. package/dist/fonts/install.js.map +1 -0
  73. package/dist/fonts/manifest.d.ts +21 -0
  74. package/dist/fonts/manifest.d.ts.map +1 -0
  75. package/dist/fonts/manifest.js +96 -0
  76. package/dist/fonts/manifest.js.map +1 -0
  77. package/dist/fonts/options.d.ts +9 -0
  78. package/dist/fonts/options.d.ts.map +1 -0
  79. package/dist/fonts/options.js +66 -0
  80. package/dist/fonts/options.js.map +1 -0
  81. package/dist/fonts/schema.d.ts +4 -0
  82. package/dist/fonts/schema.d.ts.map +1 -0
  83. package/dist/fonts/schema.js +316 -0
  84. package/dist/fonts/schema.js.map +1 -0
  85. package/dist/fonts/summary.d.ts +16 -0
  86. package/dist/fonts/summary.d.ts.map +1 -0
  87. package/dist/fonts/summary.js +22 -0
  88. package/dist/fonts/summary.js.map +1 -0
  89. package/dist/fonts/types.d.ts +56 -0
  90. package/dist/fonts/types.d.ts.map +1 -0
  91. package/dist/fonts/types.js +8 -0
  92. package/dist/fonts/types.js.map +1 -0
  93. package/dist/fonts/verify.d.ts +33 -0
  94. package/dist/fonts/verify.d.ts.map +1 -0
  95. package/dist/fonts/verify.js +200 -0
  96. package/dist/fonts/verify.js.map +1 -0
  97. package/dist/html/document-adapter.d.ts +3 -3
  98. package/dist/html/document-adapter.d.ts.map +1 -1
  99. package/dist/html/document-adapter.js +1 -1
  100. package/dist/html/document-adapter.js.map +1 -1
  101. package/dist/html/index.d.ts +1 -1
  102. package/dist/html/index.d.ts.map +1 -1
  103. package/dist/html/parse.d.ts +10 -2
  104. package/dist/html/parse.d.ts.map +1 -1
  105. package/dist/html/parse.js +14 -5
  106. package/dist/html/parse.js.map +1 -1
  107. package/dist/html/validate.d.ts +12 -1
  108. package/dist/html/validate.d.ts.map +1 -1
  109. package/dist/html/validate.js +292 -61
  110. package/dist/html/validate.js.map +1 -1
  111. package/dist/index.d.ts +4 -4
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +2 -2
  114. package/dist/index.js.map +1 -1
  115. package/dist/inspect.d.ts +61 -0
  116. package/dist/inspect.d.ts.map +1 -0
  117. package/dist/inspect.js +325 -0
  118. package/dist/inspect.js.map +1 -0
  119. package/dist/lint.d.ts +63 -0
  120. package/dist/lint.d.ts.map +1 -0
  121. package/dist/lint.js +265 -0
  122. package/dist/lint.js.map +1 -0
  123. package/dist/policy.d.ts +69 -0
  124. package/dist/policy.d.ts.map +1 -0
  125. package/dist/policy.js +361 -0
  126. package/dist/policy.js.map +1 -0
  127. package/dist/preview/main.d.ts +2 -2
  128. package/dist/preview/main.d.ts.map +1 -1
  129. package/dist/preview/main.js +35 -14
  130. package/dist/preview/main.js.map +1 -1
  131. package/dist/preview/timeline-data.d.ts +17 -65
  132. package/dist/preview/timeline-data.d.ts.map +1 -1
  133. package/dist/preview/timeline-host.d.ts.map +1 -1
  134. package/dist/preview/timeline-host.js +73 -38
  135. package/dist/preview/timeline-host.js.map +1 -1
  136. package/dist/preview/timeline-main.d.ts.map +1 -1
  137. package/dist/preview/timeline-main.js +47 -3
  138. package/dist/preview/timeline-main.js.map +1 -1
  139. package/dist/project.d.ts +13 -8
  140. package/dist/project.d.ts.map +1 -1
  141. package/dist/project.js +20 -17
  142. package/dist/project.js.map +1 -1
  143. package/dist/renderer/browser.d.ts +2 -2
  144. package/dist/renderer/browser.d.ts.map +1 -1
  145. package/dist/renderer/browser.js +10 -4
  146. package/dist/renderer/browser.js.map +1 -1
  147. package/dist/renderer/ffmpeg.d.ts +44 -1
  148. package/dist/renderer/ffmpeg.d.ts.map +1 -1
  149. package/dist/renderer/ffmpeg.js +371 -73
  150. package/dist/renderer/ffmpeg.js.map +1 -1
  151. package/dist/renderer/index.d.ts +40 -4
  152. package/dist/renderer/index.d.ts.map +1 -1
  153. package/dist/renderer/index.js +100 -25
  154. package/dist/renderer/index.js.map +1 -1
  155. package/dist/renderer/keyframe-expressions.d.ts +39 -0
  156. package/dist/renderer/keyframe-expressions.d.ts.map +1 -0
  157. package/dist/renderer/keyframe-expressions.js +180 -0
  158. package/dist/renderer/keyframe-expressions.js.map +1 -0
  159. package/dist/renderer/timeline.d.ts +2 -0
  160. package/dist/renderer/timeline.d.ts.map +1 -1
  161. package/dist/renderer/timeline.js +168 -106
  162. package/dist/renderer/timeline.js.map +1 -1
  163. package/dist/runtime/host.d.ts.map +1 -1
  164. package/dist/runtime/host.js +159 -31
  165. package/dist/runtime/host.js.map +1 -1
  166. package/dist/scaffold.d.ts +3 -0
  167. package/dist/scaffold.d.ts.map +1 -1
  168. package/dist/scaffold.js +48 -317
  169. package/dist/scaffold.js.map +1 -1
  170. package/dist/server/composition-html.d.ts +15 -7
  171. package/dist/server/composition-html.d.ts.map +1 -1
  172. package/dist/server/composition-html.js +72 -16
  173. package/dist/server/composition-html.js.map +1 -1
  174. package/dist/server/server.d.ts.map +1 -1
  175. package/dist/server/server.js +56 -6
  176. package/dist/server/server.js.map +1 -1
  177. package/dist/server/timeline-preview-data.d.ts.map +1 -1
  178. package/dist/server/timeline-preview-data.js +12 -23
  179. package/dist/server/timeline-preview-data.js.map +1 -1
  180. package/dist/server/timeline-preview-html.d.ts.map +1 -1
  181. package/dist/server/timeline-preview-html.js +20 -3
  182. package/dist/server/timeline-preview-html.js.map +1 -1
  183. package/dist/templates.d.ts +16 -0
  184. package/dist/templates.d.ts.map +1 -0
  185. package/dist/templates.js +186 -0
  186. package/dist/templates.js.map +1 -0
  187. package/dist/timeline/easing.d.ts +36 -0
  188. package/dist/timeline/easing.d.ts.map +1 -0
  189. package/dist/timeline/easing.js +225 -0
  190. package/dist/timeline/easing.js.map +1 -0
  191. package/dist/timeline/keyframes.d.ts +23 -0
  192. package/dist/timeline/keyframes.d.ts.map +1 -0
  193. package/dist/timeline/keyframes.js +95 -0
  194. package/dist/timeline/keyframes.js.map +1 -0
  195. package/dist/timeline/plan.d.ts +6 -12
  196. package/dist/timeline/plan.d.ts.map +1 -1
  197. package/dist/timeline/plan.js +17 -30
  198. package/dist/timeline/plan.js.map +1 -1
  199. package/dist/timeline/resolve.d.ts +16 -3
  200. package/dist/timeline/resolve.d.ts.map +1 -1
  201. package/dist/timeline/resolve.js +119 -13
  202. package/dist/timeline/resolve.js.map +1 -1
  203. package/dist/timeline/scene.d.ts +126 -0
  204. package/dist/timeline/scene.d.ts.map +1 -0
  205. package/dist/timeline/scene.js +109 -0
  206. package/dist/timeline/scene.js.map +1 -0
  207. package/dist/timeline/schema.d.ts +38 -0
  208. package/dist/timeline/schema.d.ts.map +1 -1
  209. package/dist/timeline/schema.js +290 -9
  210. package/dist/timeline/schema.js.map +1 -1
  211. package/dist/timeline/transitions.d.ts +21 -0
  212. package/dist/timeline/transitions.d.ts.map +1 -0
  213. package/dist/timeline/transitions.js +23 -0
  214. package/dist/timeline/transitions.js.map +1 -0
  215. package/dist/version.d.ts +1 -1
  216. package/dist/version.js +1 -1
  217. package/docs/adr/0007-make-html-documents-the-composition-unit.md +2 -2
  218. package/docs/adr/0008-share-the-composition-document-grammar.md +1 -1
  219. package/docs/adr/0010-make-timelines-the-render-unit.md +3 -2
  220. package/docs/adr/0011-compose-timeline-frames-in-a-live-browser-host.md +1 -1
  221. package/docs/adr/0012-render-timelines-with-segmented-lossless-clip-intermediates.md +1 -1
  222. package/docs/adr/0014-compose-timeline-clips-with-css-blend-modes.md +38 -0
  223. package/docs/adr/0015-inherit-composition-format-from-the-project.md +28 -0
  224. package/docs/adr/0016-author-compositions-as-html-fragments.md +32 -0
  225. package/docs/adr/0017-render-timeless-compositions-as-stills.md +99 -0
  226. package/docs/adr/0018-animate-timeline-clips-with-keyframes.md +35 -0
  227. package/docs/adr/0019-make-same-track-overlap-the-transition-window.md +36 -0
  228. package/docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md +27 -0
  229. package/docs/adr/0021-project-timeline-scenes-once.md +32 -0
  230. package/docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md +35 -0
  231. package/docs/adr/0023-pin-fonts-as-project-assets.md +98 -0
  232. package/docs/migration-0.4.md +5 -3
  233. package/docs/migration-0.8.md +163 -0
  234. package/docs/preview-testing.md +23 -3
  235. package/docs/{v0.1-design.md → v0.x-design.md} +86 -53
  236. package/examples/blend/README.md +106 -0
  237. package/examples/blend/assets/ink.mp4 +0 -0
  238. package/examples/blend/compositions/aurora.html +55 -0
  239. package/examples/blend/compositions/backdrop.html +74 -0
  240. package/examples/blend/compositions/labels.html +149 -0
  241. package/examples/blend/fy.config.js +11 -0
  242. package/examples/blend/scripts/make-ink.sh +26 -0
  243. package/examples/blend/timelines/blend.timeline.json +155 -0
  244. package/examples/demo/README.md +2 -2
  245. package/examples/demo/compositions/demo.html +243 -251
  246. package/examples/intro/README.md +71 -0
  247. package/examples/intro/assets/fonts/figtree/LICENSE.txt +93 -0
  248. package/examples/intro/assets/fonts/figtree/figtree-latin-wght-normal.woff2 +0 -0
  249. package/examples/intro/assets/fonts/instrument-serif/LICENSE.txt +93 -0
  250. package/examples/intro/assets/fonts/instrument-serif/instrument-serif-latin-400-italic.woff2 +0 -0
  251. package/examples/intro/assets/fonts/space-mono/LICENSE.txt +93 -0
  252. package/examples/intro/assets/fonts/space-mono/space-mono-latin-400-normal.woff2 +0 -0
  253. package/examples/intro/assets/fonts/space-mono/space-mono-latin-700-normal.woff2 +0 -0
  254. package/examples/intro/assets/grain.png +0 -0
  255. package/examples/intro/assets/score.ogg +0 -0
  256. package/examples/intro/compositions/brand.html +412 -0
  257. package/examples/intro/compositions/chrome.controller.js +63 -0
  258. package/examples/intro/compositions/chrome.html +256 -0
  259. package/examples/intro/compositions/lattice.controller.js +148 -0
  260. package/examples/intro/compositions/lattice.html +308 -0
  261. package/examples/intro/compositions/opening.html +504 -0
  262. package/examples/intro/compositions/studio.html +930 -0
  263. package/examples/intro/compositions/theme.css +218 -0
  264. package/examples/intro/fy.config.js +13 -0
  265. package/examples/intro/fy.fonts.json +100 -0
  266. package/examples/intro/scripts/make-grain.mjs +79 -0
  267. package/examples/intro/scripts/make-score.mjs +702 -0
  268. package/examples/intro/timelines/intro.timeline.json +60 -0
  269. package/examples/keyframes/README.md +76 -0
  270. package/examples/keyframes/compositions/backdrop.html +60 -0
  271. package/examples/keyframes/compositions/card.html +99 -0
  272. package/examples/keyframes/fy.config.js +10 -0
  273. package/examples/keyframes/timelines/keyframes.timeline.json +60 -0
  274. package/examples/nested/README.md +112 -0
  275. package/examples/nested/assets/pulse.wav +0 -0
  276. package/examples/nested/compositions/backdrop.html +84 -0
  277. package/examples/nested/compositions/card.html +275 -0
  278. package/examples/nested/compositions/overlay.html +307 -0
  279. package/examples/nested/fy.config.js +13 -0
  280. package/examples/nested/scripts/make-pulse.sh +20 -0
  281. package/examples/nested/timelines/chapter-a.timeline.json +39 -0
  282. package/examples/nested/timelines/chapter-b.timeline.json +39 -0
  283. package/examples/nested/timelines/nested-reel.timeline.json +52 -0
  284. package/examples/static/README.md +17 -0
  285. package/examples/static/compositions/still.html +37 -0
  286. package/examples/static/fy.config.js +9 -0
  287. package/examples/static/timelines/still.timeline.json +13 -0
  288. package/examples/transitions/README.md +128 -0
  289. package/examples/transitions/assets/alpha.wav +0 -0
  290. package/examples/transitions/assets/beta.wav +0 -0
  291. package/examples/transitions/assets/gamma.wav +0 -0
  292. package/examples/transitions/compositions/alpha.html +56 -0
  293. package/examples/transitions/compositions/beta.html +56 -0
  294. package/examples/transitions/compositions/gamma.html +56 -0
  295. package/examples/transitions/fy.config.js +12 -0
  296. package/examples/transitions/timelines/audio-crossfade.timeline.json +44 -0
  297. package/examples/transitions/timelines/transitions.timeline.json +31 -0
  298. package/examples/video/README.md +4 -4
  299. package/examples/video/compositions/video-mp4.html +349 -357
  300. package/examples/video/compositions/video-overlay.html +337 -345
  301. package/examples/video/compositions/video.html +349 -357
  302. package/examples/webgl/README.md +1 -1
  303. package/examples/webgl/compositions/webgl.html +205 -213
  304. package/package.json +13 -5
  305. package/scaffolds/init/AGENTS.md +131 -0
  306. package/scaffolds/init/README.md +56 -0
  307. package/scaffolds/init/compositions/hello.html +79 -0
  308. package/scaffolds/init/fy.config.js +9 -0
  309. package/scaffolds/init/gitignore.template +1 -0
  310. package/scaffolds/init/package.json +11 -0
  311. package/scaffolds/init/props/hello.json +4 -0
  312. package/scaffolds/init/props/main.json +6 -0
  313. package/scaffolds/init/timelines/main.timeline.json +20 -0
  314. package/scaffolds/local-models/LOCAL-MODELS.md +77 -0
  315. package/scaffolds/local-models/fy.policy.json +5 -0
  316. package/scaffolds/local-models/opencode/opencode.jsonc +17 -0
  317. package/scaffolds/local-models/pi/APPEND_SYSTEM.md +21 -0
  318. package/scaffolds/local-models/pi/sandbox.json +15 -0
  319. package/scaffolds/local-models/pi/settings.json +15 -0
  320. package/skills/frameyard/README.md +1 -0
  321. package/skills/frameyard/SKILL.md +59 -59
  322. package/skills/frameyard/references/audio-assets.md +32 -3
  323. package/skills/frameyard/references/common-mistakes.md +81 -7
  324. package/skills/frameyard/references/controllers.md +5 -4
  325. package/skills/frameyard/references/deterministic-authoring.md +49 -37
  326. package/skills/frameyard/references/diagnostics.md +42 -4
  327. package/skills/frameyard/references/failure-recovery.md +56 -10
  328. package/skills/frameyard/references/fonts.md +132 -0
  329. package/skills/frameyard/references/json-results.md +165 -10
  330. package/skills/frameyard/references/quick-reference.md +222 -0
  331. package/skills/frameyard/references/timelines.md +109 -15
  332. /package/examples/demo/{video.config.js → fy.config.js} +0 -0
  333. /package/examples/video/{video.config.js → fy.config.js} +0 -0
  334. /package/examples/webgl/{video.config.js → fy.config.js} +0 -0
@@ -0,0 +1,24 @@
1
+ import type { FontFamily, FontFile, FontManifest } from "./types.js";
2
+ export interface FontPayload {
3
+ /** Project-relative path below assets/fonts/<font-id>/. */
4
+ path: string;
5
+ bytes: Buffer;
6
+ /** License files may be refreshed while adding another face. */
7
+ overwrite?: boolean;
8
+ }
9
+ export interface InstallFontRecordOptions {
10
+ projectRoot: string;
11
+ manifest: FontManifest;
12
+ incoming: FontFamily;
13
+ payloads: FontPayload[];
14
+ force: boolean;
15
+ }
16
+ export interface InstallFontRecordResult {
17
+ manifest: FontManifest;
18
+ family: FontFamily;
19
+ replacedFiles: string[];
20
+ }
21
+ export declare function fontFaceKey(file: FontFile): string;
22
+ /** Merges a family record, stages every payload, and publishes the manifest atomically. */
23
+ export declare function installFontRecord(options: InstallFontRecordOptions): Promise<InstallFontRecordResult>;
24
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/fonts/install.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAEjF,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAElD;AAgHD,2FAA2F;AAC3F,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAuD3G"}
@@ -0,0 +1,145 @@
1
+ import { mkdir, rm, stat, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { publishStagedFiles, temporaryPath } from "../assets/provenance.js";
4
+ import { FrameyardError } from "../errors.js";
5
+ import { fontAssetDirectory, fontManifestPath, resolveFontAssetPath, stageFontManifest } from "./manifest.js";
6
+ import { parseFontManifest } from "./schema.js";
7
+ export function fontFaceKey(file) {
8
+ return `${file.subset ?? ""}\0${file.style}\0${fontWeightKey(file.weight)}`;
9
+ }
10
+ function fontWeightKey(weight) {
11
+ return typeof weight === "number" ? String(weight) : `${weight.min}-${weight.max}`;
12
+ }
13
+ function sortManifest(manifest) {
14
+ const fonts = [...manifest.fonts]
15
+ .sort((left, right) => left.family.localeCompare(right.family))
16
+ .map((font) => ({
17
+ ...font,
18
+ files: [...font.files].sort((left, right) => left.path.localeCompare(right.path)),
19
+ }));
20
+ return { version: manifest.version, fonts };
21
+ }
22
+ function cloneManifest(manifest) {
23
+ return {
24
+ version: manifest.version,
25
+ fonts: manifest.fonts.map((font) => ({
26
+ ...font,
27
+ license: { ...font.license },
28
+ ...(font.axes !== undefined ? { axes: { ...font.axes } } : {}),
29
+ files: font.files.map((file) => ({ ...file, weight: file.weight })),
30
+ })),
31
+ };
32
+ }
33
+ function mergeFamily(manifest, incoming, force) {
34
+ const fonts = cloneManifest(manifest).fonts;
35
+ const existingIndex = fonts.findIndex((font) => font.id === incoming.id || font.family.toLocaleLowerCase("en-US") === incoming.family.toLocaleLowerCase("en-US"));
36
+ const existing = existingIndex === -1 ? undefined : fonts[existingIndex];
37
+ const replacedFiles = [];
38
+ if (existing === undefined) {
39
+ fonts.push(incoming);
40
+ return { manifest: { version: manifest.version, fonts }, family: incoming, replacedFiles };
41
+ }
42
+ const sameFamily = existing.id === incoming.id &&
43
+ existing.family.toLocaleLowerCase("en-US") === incoming.family.toLocaleLowerCase("en-US");
44
+ if (!sameFamily || existing.provider !== incoming.provider) {
45
+ if (!force) {
46
+ throw new FrameyardError("OUTPUT_EXISTS", `Font id "${incoming.id}" or family "${incoming.family}" is already installed as "${existing.provider}". Pass --force to replace it.`);
47
+ }
48
+ replacedFiles.push(...existing.files.map((file) => file.path));
49
+ fonts[existingIndex] = incoming;
50
+ return { manifest: { version: manifest.version, fonts }, family: incoming, replacedFiles };
51
+ }
52
+ const variableMismatch = (existing.variable === true) !== (incoming.variable === true);
53
+ if (variableMismatch) {
54
+ if (!force) {
55
+ throw new FrameyardError("OUTPUT_EXISTS", `Font "${existing.family}" is already installed as ${existing.variable === true ? "variable" : "static"}. Pass --force to replace it with ${incoming.variable === true ? "variable" : "static"} files.`);
56
+ }
57
+ replacedFiles.push(...existing.files.map((file) => file.path));
58
+ fonts[existingIndex] = incoming;
59
+ return { manifest: { version: manifest.version, fonts }, family: incoming, replacedFiles };
60
+ }
61
+ for (const file of incoming.files) {
62
+ const index = existing.files.findIndex((candidate) => fontFaceKey(candidate) === fontFaceKey(file));
63
+ if (index !== -1 && !force) {
64
+ throw new FrameyardError("OUTPUT_EXISTS", `Font face ${file.style} ${fontWeightKey(file.weight)} in subset "${file.subset ?? "default"}" is already installed for "${existing.family}". Pass --force to replace it.`);
65
+ }
66
+ if (index !== -1) {
67
+ const replaced = existing.files[index];
68
+ if (replaced !== undefined) {
69
+ replacedFiles.push(replaced.path);
70
+ }
71
+ existing.files[index] = file;
72
+ }
73
+ else {
74
+ existing.files.push(file);
75
+ }
76
+ }
77
+ existing.license = {
78
+ ...existing.license,
79
+ type: incoming.license.type === "unknown" && existing.license.type !== "unknown"
80
+ ? existing.license.type
81
+ : incoming.license.type,
82
+ ...(incoming.license.file !== undefined ? { file: incoming.license.file } : {}),
83
+ ...(incoming.license.attribution !== undefined ? { attribution: incoming.license.attribution } : {}),
84
+ };
85
+ if (incoming.variable === true) {
86
+ existing.variable = true;
87
+ }
88
+ if (incoming.axes !== undefined) {
89
+ existing.axes = { ...existing.axes, ...incoming.axes };
90
+ }
91
+ return { manifest: { version: manifest.version, fonts }, family: existing, replacedFiles };
92
+ }
93
+ /** Merges a family record, stages every payload, and publishes the manifest atomically. */
94
+ export async function installFontRecord(options) {
95
+ const projectRoot = path.resolve(options.projectRoot);
96
+ const merged = mergeFamily(options.manifest, options.incoming, options.force);
97
+ const nextManifest = sortManifest(merged.manifest);
98
+ parseFontManifest(nextManifest);
99
+ const payloadByPath = new Map(options.payloads.map((payload) => [payload.path, payload]));
100
+ for (const file of options.incoming.files) {
101
+ if (!payloadByPath.has(file.path)) {
102
+ throw new FrameyardError("INTERNAL", `Missing staged payload for font file ${file.path}.`);
103
+ }
104
+ }
105
+ if (options.incoming.license.file !== undefined && !payloadByPath.has(options.incoming.license.file)) {
106
+ try {
107
+ await stat(resolveFontAssetPath(projectRoot, options.incoming.license.file));
108
+ }
109
+ catch {
110
+ throw new FrameyardError("INTERNAL", `Missing staged payload for license ${options.incoming.license.file}.`);
111
+ }
112
+ }
113
+ await mkdir(fontAssetDirectory(projectRoot, merged.family.id), { recursive: true });
114
+ const staged = [];
115
+ for (const payload of options.payloads) {
116
+ const absolute = resolveFontAssetPath(projectRoot, payload.path);
117
+ const tempPath = temporaryPath(absolute, "font-asset");
118
+ await writeFile(tempPath, payload.bytes);
119
+ staged.push({
120
+ tempPath,
121
+ path: absolute,
122
+ label: `font asset ${payload.path}`,
123
+ ...(payload.overwrite === true ? { overwrite: true } : {}),
124
+ });
125
+ }
126
+ const manifestTemp = await stageFontManifest(projectRoot, nextManifest);
127
+ staged.push({
128
+ tempPath: manifestTemp,
129
+ path: fontManifestPath(projectRoot),
130
+ label: "font manifest",
131
+ overwrite: true,
132
+ });
133
+ await publishStagedFiles(staged, { force: options.force });
134
+ for (const replaced of merged.replacedFiles) {
135
+ if (!merged.family.files.some((file) => file.path === replaced)) {
136
+ await rm(resolveFontAssetPath(projectRoot, replaced), { force: true });
137
+ }
138
+ }
139
+ return {
140
+ manifest: nextManifest,
141
+ family: nextManifest.fonts.find((font) => font.id === merged.family.id) ?? merged.family,
142
+ replacedFiles: merged.replacedFiles,
143
+ };
144
+ }
145
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/fonts/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type FontFamily, type FontManifest } from "./types.js";
2
+ export declare function fontManifestPath(projectRoot: string): string;
3
+ export declare function fontAssetDirectory(projectRoot: string, id: string): string;
4
+ export declare function resolveFontAssetPath(projectRoot: string, relativePath: string): string;
5
+ /** Reads and schema-validates the manifest. A missing manifest is not an error. */
6
+ export declare function readFontManifest(projectRoot: string): Promise<FontManifest | undefined>;
7
+ export declare function readFontManifestIfPresent(projectRoot: string): Promise<FontManifest>;
8
+ /** Writes a validated manifest to a temporary sibling file for atomic publication. */
9
+ export declare function stageFontManifest(projectRoot: string, manifest: FontManifest): Promise<string>;
10
+ export interface FontManifestSummary {
11
+ fonts: number;
12
+ files: number;
13
+ bytes: number;
14
+ }
15
+ export declare function summarizeFontManifest(manifest: FontManifest | undefined): FontManifestSummary;
16
+ export declare function uniqueFontValues(font: FontFamily): {
17
+ subsets: string[];
18
+ styles: string[];
19
+ };
20
+ export declare function fontManifestExists(projectRoot: string): Promise<boolean>;
21
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/fonts/manifest.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAOtF;AAED,mFAAmF;AACnF,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAsC7F;AAED,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAE1F;AAED,sFAAsF;AACtF,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpG;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,mBAAmB,CAU7F;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAU1F;AAED,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM9E"}
@@ -0,0 +1,96 @@
1
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { FrameyardError } from "../errors.js";
4
+ import { temporaryPath } from "../assets/provenance.js";
5
+ import { parseFontManifest } from "./schema.js";
6
+ import { FONT_ASSET_PREFIX, FONT_MANIFEST_FILENAME, emptyFontManifest, } from "./types.js";
7
+ export function fontManifestPath(projectRoot) {
8
+ return path.join(path.resolve(projectRoot), FONT_MANIFEST_FILENAME);
9
+ }
10
+ export function fontAssetDirectory(projectRoot, id) {
11
+ return path.join(path.resolve(projectRoot), FONT_ASSET_PREFIX, id);
12
+ }
13
+ export function resolveFontAssetPath(projectRoot, relativePath) {
14
+ const root = path.resolve(projectRoot);
15
+ const absolute = path.resolve(root, relativePath);
16
+ if (absolute !== root && !absolute.startsWith(root + path.sep)) {
17
+ throw new FrameyardError("FONT_MANIFEST_INVALID", `Font asset path escapes the project root: ${relativePath}`);
18
+ }
19
+ return absolute;
20
+ }
21
+ /** Reads and schema-validates the manifest. A missing manifest is not an error. */
22
+ export async function readFontManifest(projectRoot) {
23
+ const manifestPath = fontManifestPath(projectRoot);
24
+ let text;
25
+ try {
26
+ text = await readFile(manifestPath, "utf8");
27
+ }
28
+ catch (error) {
29
+ if (error.code === "ENOENT") {
30
+ return undefined;
31
+ }
32
+ throw new FrameyardError("FONT_MANIFEST_INVALID", `Could not read ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error, details: { path: manifestPath } });
33
+ }
34
+ let parsed;
35
+ try {
36
+ parsed = JSON.parse(text);
37
+ }
38
+ catch (error) {
39
+ throw new FrameyardError("FONT_MANIFEST_INVALID", `${manifestPath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, { cause: error, details: { path: manifestPath } });
40
+ }
41
+ try {
42
+ return parseFontManifest(parsed);
43
+ }
44
+ catch (error) {
45
+ if (error instanceof FrameyardError) {
46
+ throw new FrameyardError(error.code, `${manifestPath}: ${error.message}`, {
47
+ cause: error,
48
+ ...(error.details !== undefined ? { details: { path: manifestPath, ...error.details } } : {}),
49
+ });
50
+ }
51
+ throw error;
52
+ }
53
+ }
54
+ export async function readFontManifestIfPresent(projectRoot) {
55
+ return (await readFontManifest(projectRoot)) ?? emptyFontManifest();
56
+ }
57
+ /** Writes a validated manifest to a temporary sibling file for atomic publication. */
58
+ export async function stageFontManifest(projectRoot, manifest) {
59
+ parseFontManifest(manifest);
60
+ const manifestPath = fontManifestPath(projectRoot);
61
+ await mkdir(path.dirname(manifestPath), { recursive: true });
62
+ const tempPath = temporaryPath(manifestPath, "fonts");
63
+ await writeFile(tempPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
64
+ return tempPath;
65
+ }
66
+ export function summarizeFontManifest(manifest) {
67
+ let files = 0;
68
+ let bytes = 0;
69
+ for (const font of manifest?.fonts ?? []) {
70
+ files += font.files.length;
71
+ for (const file of font.files) {
72
+ bytes += file.bytes;
73
+ }
74
+ }
75
+ return { fonts: manifest?.fonts.length ?? 0, files, bytes };
76
+ }
77
+ export function uniqueFontValues(font) {
78
+ const subsets = new Set();
79
+ const styles = new Set();
80
+ for (const file of font.files) {
81
+ if (file.subset !== undefined) {
82
+ subsets.add(file.subset);
83
+ }
84
+ styles.add(file.style);
85
+ }
86
+ return { subsets: [...subsets].sort(), styles: [...styles].sort() };
87
+ }
88
+ export async function fontManifestExists(projectRoot) {
89
+ try {
90
+ return (await stat(fontManifestPath(projectRoot))).isFile();
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/fonts/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FontFormat, FontStyle, FontWeight } from "./types.js";
2
+ export declare function fontSlug(family: string): string;
3
+ export declare function parseFontWeight(value: string): FontWeight;
4
+ export declare function parseFontStyle(value: string): FontStyle;
5
+ export declare function fontFormatForPath(filePath: string): FontFormat;
6
+ export declare function formatFontWeight(weight: FontWeight): string;
7
+ export declare function fontFileStem(filePath: string): string;
8
+ export declare function safeFontFileName(filePath: string): string;
9
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/fonts/options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW/C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAczD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAKvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAc9D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAE3D;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUzD"}
@@ -0,0 +1,66 @@
1
+ import { FrameyardError } from "../errors.js";
2
+ export function fontSlug(family) {
3
+ const slug = family
4
+ .normalize("NFKD")
5
+ .replace(/[\u0300-\u036f]/g, "")
6
+ .toLowerCase()
7
+ .replace(/[^a-z0-9]+/g, "-")
8
+ .replace(/^-+|-+$/g, "");
9
+ if (slug.length === 0) {
10
+ throw new FrameyardError("FONT_MANIFEST_INVALID", `Could not derive a font id from "${family}".`);
11
+ }
12
+ return slug;
13
+ }
14
+ export function parseFontWeight(value) {
15
+ const match = /^(\d+)(?:-(\d+))?$/.exec(value.trim());
16
+ if (!match) {
17
+ throw new FrameyardError("USAGE", `--weight must be a number or an inclusive range like 100-900; received "${value}".`);
18
+ }
19
+ const min = Number(match[1]);
20
+ const max = match[2] === undefined ? min : Number(match[2]);
21
+ if (!Number.isInteger(min) || !Number.isInteger(max) || min < 1 || max > 1000 || min > max) {
22
+ throw new FrameyardError("USAGE", `--weight must be between 1 and 1000 with min <= max; received "${value}".`);
23
+ }
24
+ return match[2] === undefined ? min : { min, max };
25
+ }
26
+ export function parseFontStyle(value) {
27
+ if (value === "normal" || value === "italic") {
28
+ return value;
29
+ }
30
+ throw new FrameyardError("USAGE", `--style must be "normal" or "italic"; received "${value}".`);
31
+ }
32
+ export function fontFormatForPath(filePath) {
33
+ const extension = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
34
+ switch (extension) {
35
+ case ".woff2":
36
+ return "woff2";
37
+ case ".woff":
38
+ return "woff";
39
+ case ".ttf":
40
+ return "ttf";
41
+ case ".otf":
42
+ return "otf";
43
+ default:
44
+ throw new FrameyardError("USAGE", "Font files must use a .woff2, .woff, .ttf, or .otf extension.");
45
+ }
46
+ }
47
+ export function formatFontWeight(weight) {
48
+ return typeof weight === "number" ? String(weight) : `${weight.min}-${weight.max}`;
49
+ }
50
+ export function fontFileStem(filePath) {
51
+ const name = filePath.split(/[\\/]/).pop() ?? "font";
52
+ const dot = name.lastIndexOf(".");
53
+ return dot === -1 ? name : name.slice(0, dot);
54
+ }
55
+ export function safeFontFileName(filePath) {
56
+ const name = filePath.split(/[\\/]/).pop() ?? "font";
57
+ const extension = name.slice(name.lastIndexOf(".")).toLowerCase();
58
+ const stem = fontFileStem(name)
59
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
60
+ .replace(/^-+|-+$/g, "");
61
+ if (stem.length === 0) {
62
+ throw new FrameyardError("USAGE", `Could not derive a safe destination name from "${filePath}".`);
63
+ }
64
+ return `${stem}${extension}`;
65
+ }
66
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/fonts/options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type FontManifest } from "./types.js";
2
+ /** Parses and validates a `fy.fonts.json` document. */
3
+ export declare function parseFontManifest(value: unknown): FontManifest;
4
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/fonts/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,YAAY,EAIlB,MAAM,YAAY,CAAC;AAsTpB,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAqC9D"}