11#!/usr/bin/env node
2- import  fastGlob  from  'fast-glob' ; 
32import  { optimize }  from  'svgo' ; 
4- import  { parse }  from  'node:path' ; 
3+ import  { dirname ,  parse }  from  'node:path' ; 
4+ import  { globSync ,  writeFileSync }  from  'node:fs' ; 
55import  { readFile ,  writeFile ,  mkdir }  from  'node:fs/promises' ; 
66import  { fileURLToPath }  from  'node:url' ; 
77import  { exit }  from  'node:process' ; 
8- import  *   as   fs   from  'node:fs ' ; 
8+ import  type   { Manifest }   from  'material-icon-theme ' ; 
99
10- const  glob  =  ( pattern )  =>  fastGlob . sync ( pattern ,  { 
11-   cwd : fileURLToPath ( new  URL ( '..' ,  import . meta. url ) ) , 
12-   absolute : true , 
13- } ) ; 
10+ const  glob  =  ( pattern : string )  =>  globSync ( pattern ,  { cwd : dirname ( import . meta. dirname ) } ) ; 
1411
15- async  function  processAssetsSvgFile ( file ,  { prefix,  fullName}  =  { } )  { 
12+ type  Opts  =  { 
13+   prefix ?: string , 
14+   fullName ?: string , 
15+ } ; 
16+ 
17+ async  function  processAssetsSvgFile ( path : string ,  { prefix,  fullName} : Opts  =  { } )  { 
1618  let  name  =  fullName ; 
1719  if  ( ! name )  { 
18-     name  =  parse ( file ) . name ; 
20+     name  =  parse ( path ) . name ; 
1921    if  ( prefix )  name  =  `${ prefix } ${ name }  ; 
2022    if  ( prefix  ===  'octicon' )  name  =  name . replace ( / - [ 0 - 9 ] + $ / ,  '' ) ;  // chop of '-16' on octicons 
2123  } 
2224  // Set the `xmlns` attribute so that the files are displayable in standalone documents 
2325  // The svg backend module will strip the attribute during startup for inline display 
24-   const  { data}  =  optimize ( await  readFile ( file ,  'utf8' ) ,  { 
26+   const  { data}  =  optimize ( await  readFile ( path ,  'utf8' ) ,  { 
2527    plugins : [ 
2628      { name : 'preset-default' } , 
2729      { name : 'removeDimensions' } , 
@@ -41,33 +43,33 @@ async function processAssetsSvgFile(file, {prefix, fullName} = {}) {
4143  await  writeFile ( fileURLToPath ( new  URL ( `../public/assets/img/svg/${ name }  ,  import . meta. url ) ) ,  data ) ; 
4244} 
4345
44- function  processAssetsSvgFiles ( pattern ,  opts )  { 
45-   return  glob ( pattern ) . map ( ( file )  =>  processAssetsSvgFile ( file ,  opts ) ) ; 
46+ function  processAssetsSvgFiles ( pattern :  string ,  opts :  Opts   =   { } )  { 
47+   return  glob ( pattern ) . map ( ( path )  =>  processAssetsSvgFile ( path ,  opts ) ) ; 
4648} 
4749
4850async  function  processMaterialFileIcons ( )  { 
49-   const  files  =  glob ( 'node_modules/material-icon-theme/icons/*.svg' ) ; 
50-   const  svgSymbols  =  { } ; 
51-   for  ( const  file  of  files )  { 
51+   const  paths  =  glob ( 'node_modules/material-icon-theme/icons/*.svg' ) ; 
52+   const  svgSymbols :  Record < string ,   string >  =  { } ; 
53+   for  ( const  path  of  paths )  { 
5254    // remove all unnecessary attributes, only keep "viewBox" 
53-     const  { data}  =  optimize ( await  readFile ( file ,  'utf8' ) ,  { 
55+     const  { data}  =  optimize ( await  readFile ( path ,  'utf8' ) ,  { 
5456      plugins : [ 
5557        { name : 'preset-default' } , 
5658        { name : 'removeDimensions' } , 
5759        { name : 'removeXMLNS' } , 
5860        { name : 'removeAttrs' ,  params : { attrs : 'xml:space' ,  elemSeparator : ',' } } , 
5961      ] , 
6062    } ) ; 
61-     const  svgName  =  parse ( file ) . name ; 
63+     const  svgName  =  parse ( path ) . name ; 
6264    // intentionally use single quote here to avoid escaping 
6365    svgSymbols [ svgName ]  =  data . replace ( / " / g,  `'` ) ; 
6466  } 
65-   fs . writeFileSync ( fileURLToPath ( new  URL ( `../options/fileicon/material-icon-svgs.json` ,  import . meta. url ) ) ,  JSON . stringify ( svgSymbols ,  null ,  2 ) ) ; 
67+   writeFileSync ( fileURLToPath ( new  URL ( `../options/fileicon/material-icon-svgs.json` ,  import . meta. url ) ) ,  JSON . stringify ( svgSymbols ,  null ,  2 ) ) ; 
6668
67-   const  vscodeExtensionsJson  =  await  readFile ( fileURLToPath ( new  URL ( `generate-svg-vscode-extensions.json` ,  import . meta. url ) ) ) ; 
68-   const  vscodeExtensions  =  JSON . parse ( vscodeExtensionsJson ) ; 
69-   const  iconRulesJson  =  await  readFile ( fileURLToPath ( new  URL ( `../node_modules/material-icon-theme/dist/material-icons.json` ,  import . meta. url ) ) ) ; 
70-   const  iconRules  =  JSON . parse ( iconRulesJson ) ; 
69+   const  vscodeExtensionsJson  =  await  readFile ( fileURLToPath ( new  URL ( `generate-svg-vscode-extensions.json` ,  import . meta. url ) ) ,   'utf8' ) ; 
70+   const  vscodeExtensions  =  JSON . parse ( vscodeExtensionsJson )   as   Record < string ,   string > ; 
71+   const  iconRulesJson  =  await  readFile ( fileURLToPath ( new  URL ( `../node_modules/material-icon-theme/dist/material-icons.json` ,  import . meta. url ) ) ,   'utf8' ) ; 
72+   const  iconRules  =  JSON . parse ( iconRulesJson )   as   Manifest ; 
7173  // The rules are from VSCode material-icon-theme, we need to adjust them to our needs 
7274  // 1. We only use lowercase filenames to match (it should be good enough for most cases and more efficient) 
7375  // 2. We do not have a "Language ID" system: 
@@ -91,7 +93,7 @@ async function processMaterialFileIcons() {
9193    } 
9294  } 
9395  const  iconRulesPretty  =  JSON . stringify ( iconRules ,  null ,  2 ) ; 
94-   fs . writeFileSync ( fileURLToPath ( new  URL ( `../options/fileicon/material-icon-rules.json` ,  import . meta. url ) ) ,  iconRulesPretty ) ; 
96+   writeFileSync ( fileURLToPath ( new  URL ( `../options/fileicon/material-icon-rules.json` ,  import . meta. url ) ) ,  iconRulesPretty ) ; 
9597} 
9698
9799async  function  main ( )  { 
0 commit comments