@@ -70,6 +70,24 @@ interface ObfGrid {
7070 order ?: Array < Array < string | number | null > > ;
7171}
7272
73+ interface ObfImage {
74+ id : string ;
75+ data ?: string ;
76+ path ?: string ;
77+ url ?: string ;
78+ width ?: number ;
79+ height ?: number ;
80+ content_type ?: string ;
81+ license ?: {
82+ type ?: string ;
83+ copyright_notice_url ?: string ;
84+ source_url ?: string ;
85+ author_name ?: string ;
86+ author_url ?: string ;
87+ author_email ?: string ;
88+ } ;
89+ }
90+
7391interface ObfBoard {
7492 format ?: string ;
7593 id : string ;
@@ -79,7 +97,7 @@ interface ObfBoard {
7997 description_html ?: string ;
8098 buttons : ObfButton [ ] ;
8199 grid ?: ObfGrid ;
82- images ?: any [ ] ;
100+ images ?: ObfImage [ ] ;
83101 sounds ?: any [ ] ;
84102}
85103
@@ -132,7 +150,7 @@ class ObfProcessor extends BaseProcessor {
132150 /**
133151 * Extract an image from the ZIP file and convert to data URL
134152 */
135- private async extractImageAsDataUrl ( imageId : string , images : any [ ] ) : Promise < string | null > {
153+ private async extractImageAsDataUrl ( imageId : string , images : ObfImage [ ] ) : Promise < string | null > {
136154 // Check cache first
137155 if ( this . imageCache . has ( imageId ) ) {
138156 return this . imageCache . get ( imageId ) ?? null ;
@@ -147,8 +165,8 @@ class ObfProcessor extends BaseProcessor {
147165 }
148166
149167 // If image has data property, use that
150- if ( ( imageData as { data ?: string } ) . data ) {
151- const dataUrl = ( imageData as { data : string } ) . data ;
168+ if ( imageData . data ) {
169+ const dataUrl = imageData . data ;
152170 this . imageCache . set ( imageId , dataUrl ) ;
153171 return dataUrl ;
154172 }
@@ -158,7 +176,7 @@ class ObfProcessor extends BaseProcessor {
158176 // Images are typically stored in an 'images' folder or root
159177 const possiblePaths = [
160178 imageData . path , // Explicit path if provided
161- `images/${ imageData . filename || imageId } ` , // Standard images folder
179+ `images/${ imageData . path || imageId } ` , // Standard images folder
162180 imageData . id , // Just the ID
163181 ] . filter ( Boolean ) ;
164182
@@ -181,8 +199,8 @@ class ObfProcessor extends BaseProcessor {
181199 }
182200
183201 // If image has a URL, use that as fallback
184- if ( ( imageData as { url ?: string } ) . url ) {
185- const url = ( imageData as { url : string } ) . url ;
202+ if ( imageData . url ) {
203+ const url = imageData . url ;
186204 this . imageCache . set ( imageId , url ) ;
187205 return url ;
188206 }
@@ -654,13 +672,21 @@ class ObfProcessor extends BaseProcessor {
654672 private createObfBoardFromPage (
655673 page : AACPage ,
656674 fallbackName : string ,
657- metadata ?: AACTreeMetadata
675+ metadata ?: AACTreeMetadata ,
676+ embedData = false
658677 ) : ObfBoard {
659678 const { rows, columns, order, buttonPositions } = this . buildGridMetadata ( page ) ;
660679 const boardName =
661680 metadata ?. name && page . id === metadata ?. defaultHomePageId
662681 ? metadata . name
663682 : page . name || fallbackName ;
683+ let images : ObfImage [ ] = Array . isArray ( page . images ) ? page . images : [ ] ;
684+ if ( ! embedData ) {
685+ images = images . map ( ( image ) => {
686+ delete image . data ;
687+ return image ;
688+ } ) ;
689+ }
664690
665691 return {
666692 format : OBF_FORMAT_VERSION ,
@@ -702,7 +728,7 @@ class ObfProcessor extends BaseProcessor {
702728 hidden : button . visibility === 'Hidden' || false ,
703729 } ;
704730 } ) ,
705- images : Array . isArray ( page . images ) ? page . images : [ ] ,
731+ images,
706732 sounds : Array . isArray ( page . sounds ) ? page . sounds : [ ] ,
707733 } ;
708734 }
@@ -748,7 +774,7 @@ class ObfProcessor extends BaseProcessor {
748774 return await readBinaryFromInput ( outputPath ) ;
749775 }
750776
751- async saveFromTree ( tree : AACTree , outputPath : string ) : Promise < void > {
777+ async saveFromTree ( tree : AACTree , outputPath : string , embedData = false ) : Promise < void > {
752778 const { writeTextToPath, writeBinaryToPath, pathExists, mkDir, join } =
753779 this . options . fileAdapter ;
754780 if ( outputPath . endsWith ( '.obf' ) ) {
@@ -758,12 +784,17 @@ class ObfProcessor extends BaseProcessor {
758784 throw new Error ( 'No pages to save' ) ;
759785 }
760786
761- const obfBoard = this . createObfBoardFromPage ( rootPage , 'Exported Board' , tree . metadata ) ;
787+ const obfBoard = this . createObfBoardFromPage (
788+ rootPage ,
789+ 'Exported Board' ,
790+ tree . metadata ,
791+ embedData
792+ ) ;
762793 await writeTextToPath ( outputPath , JSON . stringify ( obfBoard , null , 2 ) ) ;
763794 } else {
764795 const getPageFilename = ( id : string ) : string => ( id . endsWith ( '.obf' ) ? id : `${ id } .obf` ) ;
765796 const files = Object . values ( tree . pages ) . map ( ( page ) => {
766- const obfBoard = this . createObfBoardFromPage ( page , 'Board' , tree . metadata ) ;
797+ const obfBoard = this . createObfBoardFromPage ( page , 'Board' , tree . metadata , embedData ) ;
767798 const obfContent = JSON . stringify ( obfBoard , null , 2 ) ;
768799 const name = getPageFilename ( page . id ) ;
769800 return {
0 commit comments