@@ -63,6 +63,20 @@ const handleScratchGuiAlert = (alertType) => {
6363const generateNonce = ( ) =>
6464 `${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } -${ Date . now ( ) . toString ( 36 ) } ` ;
6565
66+ const buildQueryString = ( params = { } ) => {
67+ const searchParams = new URLSearchParams (
68+ Object . entries ( {
69+ original_id : params . originalId ,
70+ is_copy : params . isCopy ,
71+ is_remix : params . isRemix ,
72+ title : params . title ,
73+ } ) . filter ( ( [ , value ] ) => value !== undefined ) ,
74+ ) ;
75+
76+ const queryString = searchParams . toString ( ) ;
77+ return queryString ? `?${ queryString } ` : "" ;
78+ } ;
79+
6680if ( ! projectId ) {
6781 console . error ( "project_id is required but not set" ) ;
6882} else if ( ! apiUrl ) {
@@ -80,6 +94,7 @@ if (!projectId) {
8094 requiresAuth : false ,
8195 latestAccessToken : null ,
8296 } ;
97+ let scratchFetchApi = null ;
8398
8499 const getTimeoutMessage = ( handshake ) =>
85100 handshake . requiresAuth && ! handshake . latestAccessToken
@@ -92,6 +107,36 @@ if (!projectId) {
92107 event . data ?. type === "scratch-gui-set-token" &&
93108 event . data ?. nonce === nonce ;
94109
110+ const handleUpdateProjectData = async ( currentProjectId , vmState , params ) => {
111+ if ( ! scratchFetchApi ) {
112+ throw new Error ( "Scratch fetch API not initialized" ) ;
113+ }
114+
115+ const creatingProject =
116+ currentProjectId === null || typeof currentProjectId === "undefined" ;
117+ const queryString = buildQueryString ( params ) ;
118+ const url = creatingProject
119+ ? `${ apiUrl } /api/scratch/projects/${ queryString } `
120+ : `${ apiUrl } /api/scratch/projects/${ currentProjectId } ${ queryString } ` ;
121+
122+ const response = await scratchFetchApi . scratchFetch ( url , {
123+ method : creatingProject ? "post" : "put" ,
124+ body : vmState ,
125+ headers : {
126+ "Content-Type" : "application/json" ,
127+ } ,
128+ credentials : "include" ,
129+ } ) ;
130+
131+ if ( response . status !== 200 ) {
132+ throw response . status ;
133+ }
134+
135+ const body = await response . json ( ) ;
136+ body . id = creatingProject ? body [ "content-name" ] : currentProjectId ;
137+ return body ;
138+ } ;
139+
95140 const mountGui = ( accessToken ) => {
96141 if ( isMounted ) return ;
97142 isMounted = true ;
@@ -108,10 +153,12 @@ if (!projectId) {
108153 assetHost = { `${ apiUrl } /api/scratch/assets` }
109154 basePath = { `${ process . env . ASSETS_URL } /scratch-gui/` }
110155 onStorageInit = { ( storage ) => {
156+ scratchFetchApi = storage . scratchFetch ;
111157 if ( accessToken ) {
112- storage . scratchFetch . setMetadata ( "Authorization" , accessToken ) ;
158+ scratchFetchApi . setMetadata ( "Authorization" , accessToken ) ;
113159 }
114160 } }
161+ onUpdateProjectData = { handleUpdateProjectData }
115162 onUpdateProjectId = { handleUpdateProjectId }
116163 onShowCreatingRemixAlert = { handleRemixingStarted }
117164 onShowRemixSuccessAlert = { handleRemixingSucceeded }
0 commit comments