@@ -17,6 +17,7 @@ import { isAudioFile } from "../helpers/mime.js";
1717import { generateWaveformCache } from "../helpers/waveform.js" ;
1818import { validateUploadedMediaBuffer } from "../helpers/mediaValidation.js" ;
1919import { isSafePath } from "../helpers/safePath.js" ;
20+ import type { GsapAnimation } from "../../parsers/gsapSerialize.js" ;
2021import {
2122 removeElementFromHtml ,
2223 patchElementInHtml ,
@@ -600,26 +601,44 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {
600601 removeAnimationFromScript,
601602 } = await loadGsapParser ( ) ;
602603
604+ function requireAnimation (
605+ scriptText : string ,
606+ animationId : string ,
607+ ) : { anim : GsapAnimation } | { err : Response } {
608+ const parsed = parseGsapScript ( scriptText ) ;
609+ const anim = parsed . animations . find ( ( a ) => a . id === animationId ) ;
610+ if ( ! anim ) return { err : c . json ( { error : "animation not found" } , 404 ) } ;
611+ return { anim } ;
612+ }
613+
614+ function requireFromToAnimation (
615+ scriptText : string ,
616+ animationId : string ,
617+ ) : { anim : GsapAnimation } | { err : Response } {
618+ const result = requireAnimation ( scriptText , animationId ) ;
619+ if ( "err" in result ) return result ;
620+ if ( result . anim . method !== "fromTo" )
621+ return { err : c . json ( { error : "animation is not a fromTo" } , 400 ) } ;
622+ return result ;
623+ }
624+
603625 let newScript : string ;
604626
605627 // fallow-ignore-next-line complexity
606628 switch ( body . type ) {
607629 case "update-property" : {
608- const parsed = parseGsapScript ( block . scriptText ) ;
609- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
610- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
630+ const r = requireAnimation ( block . scriptText , body . animationId ) ;
631+ if ( "err" in r ) return r . err ;
611632 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
612- properties : { ...anim . properties , [ body . property ] : body . value } ,
633+ properties : { ...r . anim . properties , [ body . property ] : body . value } ,
613634 } ) ;
614635 break ;
615636 }
616637 case "update-from-property" : {
617- const parsed = parseGsapScript ( block . scriptText ) ;
618- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
619- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
620- if ( anim . method !== "fromTo" ) return c . json ( { error : "animation is not a fromTo" } , 400 ) ;
638+ const r = requireFromToAnimation ( block . scriptText , body . animationId ) ;
639+ if ( "err" in r ) return r . err ;
621640 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
622- fromProperties : { ...( anim . fromProperties ?? { } ) , [ body . property ] : body . value } ,
641+ fromProperties : { ...( r . anim . fromProperties ?? { } ) , [ body . property ] : body . value } ,
623642 } ) ;
624643 break ;
625644 }
@@ -628,6 +647,9 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {
628647 break ;
629648 }
630649 case "add" : {
650+ if ( body . fromProperties && body . method !== "fromTo" ) {
651+ return c . json ( { error : "fromProperties is only valid for method=fromTo" } , 400 ) ;
652+ }
631653 const result = addAnimationToScript ( block . scriptText , {
632654 targetSelector : body . targetSelector ,
633655 method : body . method ,
@@ -645,41 +667,35 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {
645667 break ;
646668 }
647669 case "add-property" : {
648- const parsed = parseGsapScript ( block . scriptText ) ;
649- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
650- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
670+ const r = requireAnimation ( block . scriptText , body . animationId ) ;
671+ if ( "err" in r ) return r . err ;
651672 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
652- properties : { ...anim . properties , [ body . property ] : body . defaultValue } ,
673+ properties : { ...r . anim . properties , [ body . property ] : body . defaultValue } ,
653674 } ) ;
654675 break ;
655676 }
656677 case "add-from-property" : {
657- const parsed = parseGsapScript ( block . scriptText ) ;
658- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
659- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
660- if ( anim . method !== "fromTo" ) return c . json ( { error : "animation is not a fromTo" } , 400 ) ;
678+ const r = requireFromToAnimation ( block . scriptText , body . animationId ) ;
679+ if ( "err" in r ) return r . err ;
661680 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
662- fromProperties : { ...( anim . fromProperties ?? { } ) , [ body . property ] : body . defaultValue } ,
681+ fromProperties : { ...( r . anim . fromProperties ?? { } ) , [ body . property ] : body . defaultValue } ,
663682 } ) ;
664683 break ;
665684 }
666685 case "remove-property" : {
667- const parsed = parseGsapScript ( block . scriptText ) ;
668- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
669- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
670- const filtered = { ...anim . properties } ;
686+ const r = requireAnimation ( block . scriptText , body . animationId ) ;
687+ if ( "err" in r ) return r . err ;
688+ const filtered = { ...r . anim . properties } ;
671689 delete filtered [ body . property ] ;
672690 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
673691 properties : filtered ,
674692 } ) ;
675693 break ;
676694 }
677695 case "remove-from-property" : {
678- const parsed = parseGsapScript ( block . scriptText ) ;
679- const anim = parsed . animations . find ( ( a ) => a . id === body . animationId ) ;
680- if ( ! anim ) return c . json ( { error : "animation not found" } , 404 ) ;
681- if ( anim . method !== "fromTo" ) return c . json ( { error : "animation is not a fromTo" } , 400 ) ;
682- const filtered = { ...( anim . fromProperties ?? { } ) } ;
696+ const r = requireFromToAnimation ( block . scriptText , body . animationId ) ;
697+ if ( "err" in r ) return r . err ;
698+ const filtered = { ...( r . anim . fromProperties ?? { } ) } ;
683699 delete filtered [ body . property ] ;
684700 newScript = updateAnimationInScript ( block . scriptText , body . animationId , {
685701 fromProperties : filtered ,
0 commit comments