1
1
#!/usr/bin/env node
2
- import fastGlob from 'fast-glob' ;
3
2
import { optimize } from 'svgo' ;
4
- import { parse } from 'node:path' ;
3
+ import { dirname , parse } from 'node:path' ;
4
+ import { globSync , writeFileSync } from 'node:fs' ;
5
5
import { readFile , writeFile , mkdir } from 'node:fs/promises' ;
6
6
import { fileURLToPath } from 'node:url' ;
7
7
import { exit } from 'node:process' ;
8
- import * as fs from 'node:fs ' ;
8
+ import type { Manifest } from 'material-icon-theme ' ;
9
9
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 ) } ) ;
14
11
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 = { } ) {
16
18
let name = fullName ;
17
19
if ( ! name ) {
18
- name = parse ( file ) . name ;
20
+ name = parse ( path ) . name ;
19
21
if ( prefix ) name = `${ prefix } -${ name } ` ;
20
22
if ( prefix === 'octicon' ) name = name . replace ( / - [ 0 - 9 ] + $ / , '' ) ; // chop of '-16' on octicons
21
23
}
22
24
// Set the `xmlns` attribute so that the files are displayable in standalone documents
23
25
// 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' ) , {
25
27
plugins : [
26
28
{ name : 'preset-default' } ,
27
29
{ name : 'removeDimensions' } ,
@@ -41,33 +43,33 @@ async function processAssetsSvgFile(file, {prefix, fullName} = {}) {
41
43
await writeFile ( fileURLToPath ( new URL ( `../public/assets/img/svg/${ name } .svg` , import . meta. url ) ) , data ) ;
42
44
}
43
45
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 ) ) ;
46
48
}
47
49
48
50
async 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 ) {
52
54
// remove all unnecessary attributes, only keep "viewBox"
53
- const { data} = optimize ( await readFile ( file , 'utf8' ) , {
55
+ const { data} = optimize ( await readFile ( path , 'utf8' ) , {
54
56
plugins : [
55
57
{ name : 'preset-default' } ,
56
58
{ name : 'removeDimensions' } ,
57
59
{ name : 'removeXMLNS' } ,
58
60
{ name : 'removeAttrs' , params : { attrs : 'xml:space' , elemSeparator : ',' } } ,
59
61
] ,
60
62
} ) ;
61
- const svgName = parse ( file ) . name ;
63
+ const svgName = parse ( path ) . name ;
62
64
// intentionally use single quote here to avoid escaping
63
65
svgSymbols [ svgName ] = data . replace ( / " / g, `'` ) ;
64
66
}
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 ) ) ;
66
68
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 ;
71
73
// The rules are from VSCode material-icon-theme, we need to adjust them to our needs
72
74
// 1. We only use lowercase filenames to match (it should be good enough for most cases and more efficient)
73
75
// 2. We do not have a "Language ID" system:
@@ -91,7 +93,7 @@ async function processMaterialFileIcons() {
91
93
}
92
94
}
93
95
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 ) ;
95
97
}
96
98
97
99
async function main ( ) {
0 commit comments