@@ -73,6 +73,9 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
7373 liveGit . setProjectRoot ( projectRoot ) ;
7474 return liveGit . getFileContentAtCommit ( hash , repoPath ) ;
7575 } ;
76+ const gitStateStart = GIT_STATE_START ;
77+ const gitStateEnd = GIT_STATE_END ;
78+ let initialSerializedGitState : string | undefined ;
7679 let collectedGitInformation : Map < string , BuildGitTrackingInfo > | undefined ;
7780 let retainedContentFiles : Set < string > | undefined ;
7881
@@ -84,14 +87,20 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
8487 } ,
8588 transform ( code , id ) {
8689 if ( id !== '\0astro:data-layer-content' ) return ;
87- const exportPrefix = 'export default ' ;
88- const exportStart = code . lastIndexOf ( exportPrefix ) ;
89- if ( exportStart === - 1 ) return ;
90-
91- const serializedContent = code
92- . slice ( exportStart + exportPrefix . length )
93- . trim ( )
94- . replace ( / ; $ / , '' ) ;
90+ const ast = this . parse ( code ) ;
91+ const defaultExport = ast . body . find ( ( node ) => node . type === 'ExportDefaultDeclaration' ) ;
92+ if (
93+ defaultExport ?. type !== 'ExportDefaultDeclaration' ||
94+ typeof defaultExport . declaration . start !== 'number' ||
95+ typeof defaultExport . declaration . end !== 'number'
96+ ) {
97+ return ;
98+ }
99+
100+ const serializedContent = code . slice (
101+ defaultExport . declaration . start ,
102+ defaultExport . declaration . end
103+ ) ;
95104 try {
96105 const contentMap : Map < string , Map < string , unknown > > = devalue . unflatten (
97106 JSON . parse ( serializedContent )
@@ -136,13 +145,16 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
136145 if ( gitStateIsDedicated && contentDataEntrypoint ) {
137146 await cleanupState ( contentDataEntrypoint , gitStateEntrypoint , loadCommitContent ) ;
138147 } else {
139- if ( retainedContentFiles === undefined ) {
148+ if ( retainedContentFiles === undefined || initialSerializedGitState === undefined ) {
140149 throw new Error ( 'Could not determine retained content files for combined output' ) ;
141150 }
142151 cleanupCombinedState (
143152 gitStateEntrypoint ,
144153 collectedGitInformation ! ,
145154 retainedContentFiles ,
155+ initialSerializedGitState ,
156+ gitStateStart ,
157+ gitStateEnd ,
146158 loadCommitContent
147159 ) ;
148160 }
@@ -166,9 +178,14 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
166178 collectedGitInformation = new Map ( trackedFiles ) ;
167179 debug ( 'Git tracked file dates:' , trackedFiles ) ;
168180
169- const serializedState = serializeGitState ( collectedGitInformation ) ;
170- return `const trackedFilesPayload = ${ JSON . stringify ( serializedState ) } ;
171- const trackedFiles = JSON.parse(atob(trackedFilesPayload.slice(${ GIT_STATE_START . length } , -${ GIT_STATE_END . length } )));
181+ initialSerializedGitState = serializeGitState (
182+ collectedGitInformation ,
183+ gitStateStart ,
184+ gitStateEnd
185+ ) ;
186+ return `const trackedFilesPayload = ${ JSON . stringify ( initialSerializedGitState ) } ;
187+ const trackedFilesBytes = Uint8Array.from(atob(trackedFilesPayload.slice(${ gitStateStart . length } , -${ gitStateEnd . length } )), (byte) => byte.charCodeAt(0));
188+ const trackedFiles = JSON.parse(new TextDecoder().decode(trackedFilesBytes));
172189export { trackedFiles as default };` ;
173190 }
174191 } ,
@@ -185,8 +202,12 @@ type BuildGitTrackingInfo = {
185202 commits : BuildCommitInfo [ ] ;
186203} ;
187204
188- function serializeGitState ( gitInformation : Map < string , BuildGitTrackingInfo > ) : string {
189- return `${ GIT_STATE_START } ${ Buffer . from ( devalue . stringify ( gitInformation ) ) . toString ( 'base64' ) } ${ GIT_STATE_END } ` ;
205+ function serializeGitState (
206+ gitInformation : Map < string , BuildGitTrackingInfo > ,
207+ stateStart : string ,
208+ stateEnd : string
209+ ) : string {
210+ return `${ stateStart } ${ Buffer . from ( devalue . stringify ( gitInformation ) ) . toString ( 'base64' ) } ${ stateEnd } ` ;
190211}
191212
192213function materializeCommitContent (
@@ -259,6 +280,9 @@ function cleanupCombinedState(
259280 gitState : string ,
260281 gitInformation : Map < string , BuildGitTrackingInfo > ,
261282 retainedContentFiles : Set < string > ,
283+ initialSerializedState : string ,
284+ stateStartToken : string ,
285+ stateEndToken : string ,
262286 loadCommitContent : ( hash : string , repoPath : string ) => string
263287) : void {
264288 const retainedGitInformation = new Map (
@@ -269,17 +293,22 @@ function cleanupCombinedState(
269293 }
270294
271295 const originalContent = readFileSync ( gitState , 'utf-8' ) ;
272- const stateStart = originalContent . indexOf ( GIT_STATE_START ) ;
273- const stateEnd = originalContent . lastIndexOf ( GIT_STATE_END ) ;
274- if ( stateStart === - 1 || stateEnd === - 1 ) {
275- throw new Error ( 'Could not locate serialized Git history in the combined output chunk' ) ;
296+ const stateStart = originalContent . indexOf ( initialSerializedState ) ;
297+ if (
298+ stateStart === - 1 ||
299+ originalContent . indexOf ( initialSerializedState , stateStart + initialSerializedState . length ) !==
300+ - 1
301+ ) {
302+ throw new Error (
303+ 'Could not uniquely locate serialized Git history in the combined output chunk'
304+ ) ;
276305 }
277306
278- const serializedState = serializeGitState ( retainedGitInformation ) ;
307+ const serializedState = serializeGitState ( retainedGitInformation , stateStartToken , stateEndToken ) ;
279308 writeFileSync (
280309 gitState ,
281310 `${ originalContent . slice ( 0 , stateStart ) } ${ serializedState } ${ originalContent . slice (
282- stateEnd + GIT_STATE_END . length
311+ stateStart + initialSerializedState . length
283312 ) } `,
284313 'utf-8'
285314 ) ;
0 commit comments