1- import { writeFileSync , mkdirSync } from 'fs' ;
1+ import { writeFileSync , mkdirSync , rmSync } from 'fs' ;
22import { join , dirname } from 'path' ;
33import { fileURLToPath } from 'url' ;
44
@@ -12,6 +12,7 @@ if (!MODULAR_CLOUD_API_TOKEN || !MODULAR_CLOUD_ORG || !MODULAR_CLOUD_BASE_URL) {
1212}
1313
1414const API_DOMAIN = 'api.modular.com' ;
15+ const JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/modularml/modular-webflow@master/data/images' ;
1516
1617const headers = {
1718 'X-Yatai-Api-Token' : MODULAR_CLOUD_API_TOKEN ,
@@ -45,6 +46,31 @@ function toSubdomain(displayName) {
4546 . replace ( / ^ - | - $ / g, '' ) ;
4647}
4748
49+ const MIME_TO_EXT = {
50+ 'image/png' : '.png' ,
51+ 'image/svg+xml' : '.svg' ,
52+ 'image/jpeg' : '.jpg' ,
53+ 'image/jpg' : '.jpg' ,
54+ 'image/gif' : '.gif' ,
55+ 'image/webp' : '.webp' ,
56+ } ;
57+
58+ function parseDataUri ( dataUri ) {
59+ if ( ! dataUri || ! dataUri . startsWith ( 'data:' ) ) return null ;
60+
61+ const match = dataUri . match ( / ^ d a t a : ( [ ^ ; ] + ) ; b a s e 6 4 , ( .+ ) $ / s) ;
62+ if ( ! match ) return null ;
63+
64+ const [ , mime , payload ] = match ;
65+ const ext = MIME_TO_EXT [ mime ] ;
66+ if ( ! ext ) return null ;
67+
68+ const buffer = Buffer . from ( payload , 'base64' ) ;
69+ if ( buffer . length === 0 ) return null ;
70+
71+ return { mime, ext, buffer } ;
72+ }
73+
4874function transformModel ( model , endpointUrl ) {
4975 const meta = model . metadata || { } ;
5076 const tags = meta . tags || [ ] ;
@@ -72,6 +98,9 @@ function transformModel(model, endpointUrl) {
7298
7399async function processModelGarden ( modelGarden ) {
74100 const results = [ ] ;
101+ const imagesDir = join ( __dirname , '..' , 'data' , 'images' ) ;
102+ rmSync ( imagesDir , { recursive : true , force : true } ) ;
103+ mkdirSync ( imagesDir , { recursive : true } ) ;
75104
76105 for ( const model of modelGarden . items ) {
77106 let endpointUrl ;
@@ -89,7 +118,22 @@ async function processModelGarden(modelGarden) {
89118 endpointUrl = `https://${ subdomain } .${ API_DOMAIN } ` ;
90119 }
91120
92- results . push ( transformModel ( model , endpointUrl ) ) ;
121+ const transformed = transformModel ( model , endpointUrl ) ;
122+
123+ const parsed = parseDataUri ( transformed . logo_url ) ;
124+ if ( parsed ) {
125+ try {
126+ const filename = `${ transformed . name } ${ parsed . ext } ` ;
127+ writeFileSync ( join ( imagesDir , filename ) , parsed . buffer ) ;
128+ transformed . logo_url = `${ JSDELIVR_BASE } /${ filename } ` ;
129+ console . log ( `Saved image for ${ transformed . name } : ${ filename } ` ) ;
130+ } catch ( err ) {
131+ console . error ( `Failed to save image for ${ transformed . name } : ${ err . message } ` ) ;
132+ transformed . logo_url = null ;
133+ }
134+ }
135+
136+ results . push ( transformed ) ;
93137 }
94138
95139 return results ;
0 commit comments