2018-08-26 23:23:57 +02:00
#!/usr/bin/env node
/ * *
* @ fileoverview
* Compiles our icons into static . js files that can be imported in the browser
2021-02-08 18:14:31 +02:00
* and are tree - shakeable . The static . js files go in icons / { filename } . js . Also
* generates an index . js that exports all icons by title , but is not
* tree - shakeable
2018-08-26 23:23:57 +02:00
* /
2021-10-25 21:13:10 +02:00
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
const util = require ( 'util' ) ;
const { minify } = require ( 'uglify-js' ) ;
2019-07-14 21:05:38 +02:00
2021-10-25 21:13:10 +02:00
const UTF8 = 'utf8' ;
2019-08-15 13:23:35 +02:00
2021-10-25 21:13:10 +02:00
const rootDir = path . resolve ( _ _dirname , '..' , '..' ) ;
const dataFile = path . resolve ( rootDir , '_data' , 'simple-icons.json' ) ;
const indexFile = path . resolve ( rootDir , 'index.js' ) ;
const iconsDir = path . resolve ( rootDir , 'icons' ) ;
2021-10-29 01:16:34 +02:00
const iconsJsFile = path . resolve ( rootDir , 'icons.js' ) ;
const iconsMjsFile = path . resolve ( rootDir , 'icons.mjs' ) ;
const iconsDtsFile = path . resolve ( rootDir , 'icons.d.ts' ) ;
2019-08-15 13:23:35 +02:00
2021-10-25 21:13:10 +02:00
const templatesDir = path . resolve ( _ _dirname , 'templates' ) ;
const indexTemplateFile = path . resolve ( templatesDir , 'index.js' ) ;
const iconObjectTemplateFile = path . resolve ( templatesDir , 'icon-object.js' ) ;
2019-08-15 13:23:35 +02:00
const indexTemplate = fs . readFileSync ( indexTemplateFile , UTF8 ) ;
const iconObjectTemplate = fs . readFileSync ( iconObjectTemplateFile , UTF8 ) ;
2018-08-26 23:23:57 +02:00
2019-07-14 21:05:38 +02:00
const data = require ( dataFile ) ;
2021-11-08 12:55:47 +02:00
const {
getIconSlug ,
svgToPath ,
titleToHtmlFriendly ,
slugToVariableName ,
} = require ( '../utils.js' ) ;
2018-08-26 23:23:57 +02:00
2019-07-14 17:07:24 +02:00
// Local helper functions
2021-10-25 21:13:10 +02:00
const escape = ( value ) => {
2020-07-28 12:33:40 +02:00
return value . replace ( /(?<!\\)'/g , "\\'" ) ;
2021-10-25 21:13:10 +02:00
} ;
const iconToKeyValue = ( icon ) => {
2021-05-25 18:40:11 +02:00
return ` ' ${ icon . slug } ': ${ iconToObject ( icon ) } ` ;
2021-10-25 21:13:10 +02:00
} ;
const licenseToObject = ( license ) => {
2021-03-02 14:01:31 +02:00
if ( license === undefined ) {
return ;
}
if ( license . url === undefined ) {
2021-04-15 18:33:25 +02:00
license . url = ` https://spdx.org/licenses/ ${ license . type } ` ;
2021-03-02 14:01:31 +02:00
}
return license ;
2021-10-25 21:13:10 +02:00
} ;
const iconToObject = ( icon ) => {
return util . format (
iconObjectTemplate ,
2019-08-15 13:23:35 +02:00
escape ( icon . title ) ,
escape ( icon . slug ) ,
2021-11-06 17:03:37 +02:00
escape ( titleToHtmlFriendly ( icon . title ) ) ,
escape ( icon . path ) ,
2019-08-15 13:23:35 +02:00
escape ( icon . source ) ,
2021-03-02 14:01:31 +02:00
escape ( icon . hex ) ,
2021-03-26 11:33:04 +02:00
icon . guidelines ? ` ' ${ escape ( icon . guidelines ) } ' ` : undefined ,
2021-03-02 14:01:31 +02:00
licenseToObject ( icon . license ) ,
2019-08-15 13:23:35 +02:00
) ;
2021-10-25 21:13:10 +02:00
} ;
2021-10-29 01:16:34 +02:00
const writeJs = ( filepath , rawJavaScript ) => {
2021-02-08 18:14:31 +02:00
const { error , code } = minify ( rawJavaScript ) ;
if ( error ) {
console . error ( error ) ;
process . exit ( 1 ) ;
} else {
fs . writeFileSync ( filepath , code ) ;
}
2021-10-25 21:13:10 +02:00
} ;
2021-10-29 01:16:34 +02:00
const writeTs = ( filepath , rawTypeScript ) => {
fs . writeFileSync ( filepath , rawTypeScript ) ;
} ;
2019-07-14 17:07:24 +02:00
// 'main'
2021-10-29 01:16:34 +02:00
const iconsBarrelMjs = [ ] ;
const iconsBarrelJs = [ ] ;
const iconsBarrelDts = [ ] ;
2019-07-14 17:07:24 +02:00
const icons = [ ] ;
2021-10-25 21:13:10 +02:00
data . icons . forEach ( ( icon ) => {
2021-02-22 15:15:37 +02:00
const filename = getIconSlug ( icon ) ;
2021-02-08 18:14:31 +02:00
const svgFilepath = path . resolve ( iconsDir , ` ${ filename } .svg ` ) ;
icon . svg = fs . readFileSync ( svgFilepath , UTF8 ) . replace ( /\r?\n/ , '' ) ;
2021-11-06 17:03:37 +02:00
icon . path = svgToPath ( icon . svg ) ;
2021-02-08 18:14:31 +02:00
icon . slug = filename ;
icons . push ( icon ) ;
2019-08-15 13:23:35 +02:00
2021-10-29 01:16:34 +02:00
const iconObject = iconToObject ( icon ) ;
2021-11-23 22:33:37 +02:00
const iconExportName = slugToVariableName ( icon . slug ) ;
2021-10-29 01:16:34 +02:00
2021-02-08 18:14:31 +02:00
// write the static .js file for the icon
const jsFilepath = path . resolve ( iconsDir , ` ${ filename } .js ` ) ;
2021-11-23 22:33:37 +02:00
const newImportMessage = ` use "const { ${ iconExportName } } = require('simple-icons/icons');" instead ` ;
const message = JSON . stringify (
` Imports like "const ${ icon . slug } = require('simple-icons/icons/ ${ icon . slug } ');" have been deprecated in v6.0.0 and will no longer work from v7.0.0, ${ newImportMessage } ` ,
) ;
writeJs (
jsFilepath ,
` console.warn("warn -", ${ message } );module.exports= ${ iconObject } ; ` ,
) ;
2021-10-29 01:16:34 +02:00
const dtsFilepath = path . resolve ( iconsDir , ` ${ filename } .d.ts ` ) ;
writeTs (
dtsFilepath ,
2021-11-23 22:33:37 +02:00
` /**@deprecated ${ newImportMessage } */declare const i:import("../alias").I;export default i; ` ,
2021-10-29 01:16:34 +02:00
) ;
// add object to the barrel file
iconsBarrelJs . push ( ` ${ iconExportName } : ${ iconObject } , ` ) ;
iconsBarrelMjs . push ( ` export const ${ iconExportName } = ${ iconObject } ` ) ;
iconsBarrelDts . push ( ` export const ${ iconExportName } :I; ` ) ;
2018-08-26 23:23:57 +02:00
} ) ;
// write our generic index.js
2021-10-25 21:13:10 +02:00
const rawIndexJs = util . format (
indexTemplate ,
icons . map ( iconToKeyValue ) . join ( ',' ) ,
) ;
2021-10-29 01:16:34 +02:00
writeJs ( indexFile , rawIndexJs ) ;
// write our file containing the exports of all icons in CommonJS ...
const rawIconsJs = ` module.exports={ ${ iconsBarrelJs . join ( '' ) } }; ` ;
writeJs ( iconsJsFile , rawIconsJs ) ;
// and ESM
const rawIconsMjs = iconsBarrelMjs . join ( '' ) ;
writeJs ( iconsMjsFile , rawIconsMjs ) ;
// and create a type declaration file
const rawIconsDts = ` import {I} from "./alias"; ${ iconsBarrelDts . join ( '' ) } ` ;
writeTs ( iconsDtsFile , rawIconsDts ) ;