@@ -24,14 +24,15 @@ import * as fs from "fs";
2424import { join as pathJoin , relative as pathRelative } from "path" ;
2525import { assert } from "tsafe/assert" ;
2626import { exclude } from "tsafe/exclude" ;
27- import { writeFile , readFile , rm } from "fs/promises" ;
27+ import { writeFile , readFile , rm , cp } from "fs/promises" ;
2828import { crawl } from "./tools/crawl" ;
2929import { basename as pathBasename , sep as pathSep , dirname as pathDirname } from "path" ;
3030import type { Equals } from "tsafe" ;
3131import yargsParser from "yargs-parser" ;
3232import { getAbsoluteAndInOsFormatPath } from "./tools/getAbsoluteAndInOsFormatPath" ;
3333import { readPublicDirPath } from "./readPublicDirPath" ;
3434import { existsAsync } from "./tools/fs.existsAsync" ;
35+ import { fnv1aHashToHex } from "./tools/fnv1aHashToHex" ;
3536
3637export const pathOfIconsJson = pathJoin ( "utility" , "icons" , "icons.json" ) ;
3738
@@ -460,55 +461,106 @@ async function main() {
460461 "utf8"
461462 ) ;
462463
463- const onConfirmedChange = async ( ) => {
464- const nextCacheDir = pathJoin ( projectDirPath , ".next" , "cache" ) ;
464+ let hasChanged = false ;
465465
466- if ( ! fs . existsSync ( nextCacheDir ) ) {
467- return ;
468- }
466+ const utilityIconsRelativeDirPath = pathJoin ( "utility" , "icons" ) ;
469467
470- await rm ( nextCacheDir , { "recursive" : true , "force" : true } ) ;
471- } ;
468+ await Promise . all (
469+ [ dsfrDistInNodeModulesDirPath , dsfrDistInPublicDirPath ]
470+ . filter ( exclude ( undefined ) )
471+ . map ( async dsfrDistDirPath => {
472+ const cssFilePath = pathJoin (
473+ dsfrDistDirPath ,
474+ utilityIconsRelativeDirPath ,
475+ "icons.min.css"
476+ ) ;
472477
473- console . log ( { dsfrDistInPublicDirPath } ) ;
478+ if ( ! fs . existsSync ( cssFilePath ) ) {
479+ return ;
480+ }
474481
475- [ dsfrDistInNodeModulesDirPath , dsfrDistInPublicDirPath ]
476- . filter ( exclude ( undefined ) )
477- . forEach ( async dsfrDistDirPath => {
478- const cssFilePath = pathJoin ( dsfrDistDirPath , "utility" , "icons" , "icons.min.css" ) ;
482+ const remixiconDirPath = pathJoin ( dsfrDistDirPath , "icons" , "remixicon" ) ;
479483
480- if ( ! fs . existsSync ( cssFilePath ) ) {
481- return ;
482- }
484+ if ( ! fs . existsSync ( remixiconDirPath ) ) {
485+ fs . mkdirSync ( remixiconDirPath ) ;
486+ }
483487
484- const remixiconDirPath = pathJoin ( dsfrDistDirPath , "icons" , "remixicon" ) ;
488+ usedIcons
489+ . map ( icon => ( icon . prefix !== "ri-" ? undefined : icon ) )
490+ . filter ( exclude ( undefined ) )
491+ . map ( ( { iconId, rawSvgCode } ) =>
492+ writeFile (
493+ pathJoin ( remixiconDirPath , `${ iconId } .svg` ) ,
494+ Buffer . from ( rawSvgCode , "utf8" )
495+ )
496+ ) ;
485497
486- if ( ! fs . existsSync ( remixiconDirPath ) ) {
487- fs . mkdirSync ( remixiconDirPath ) ;
488- }
498+ log ?. ( `Patching ${ pathRelative ( projectDirPath , cssFilePath ) } ` ) ;
489499
490- usedIcons
491- . map ( icon => ( icon . prefix !== "ri-" ? undefined : icon ) )
492- . filter ( exclude ( undefined ) )
493- . map ( ( { iconId, rawSvgCode } ) =>
500+ const dynamicFilePath = pathJoin (
501+ pathDirname ( cssFilePath ) ,
502+ `icons.${ fnv1aHashToHex ( rawIconCssCodeBuffer . toString ( "utf8" ) ) } .css`
503+ ) ;
504+
505+ if ( fs . existsSync ( dynamicFilePath ) ) {
506+ return ;
507+ }
508+
509+ fs . readdirSync ( pathDirname ( cssFilePath ) )
510+ . filter (
511+ fileBasename =>
512+ fileBasename . startsWith ( "icons." ) && fileBasename . endsWith ( ".css" )
513+ )
514+ . map ( fileBasename => pathJoin ( pathDirname ( cssFilePath ) , fileBasename ) )
515+ . forEach ( filePath => fs . unlinkSync ( filePath ) ) ;
516+
517+ await Promise . all ( [
518+ writeFile ( dynamicFilePath , rawIconCssCodeBuffer ) ,
494519 writeFile (
495- pathJoin ( remixiconDirPath , ` ${ iconId } .svg` ) ,
496- Buffer . from ( rawSvgCode , "utf8" )
520+ cssFilePath ,
521+ Buffer . from ( `@import url("./ ${ pathBasename ( dynamicFilePath ) } ");` , "utf8" )
497522 )
498- ) ;
523+ ] ) ;
499524
500- log ?. ( `Patching ${ pathRelative ( projectDirPath , cssFilePath ) } ` ) ;
525+ hasChanged = true ;
526+ } )
527+ ) ;
501528
502- const currentCode = await readFile ( cssFilePath ) ;
529+ clear_next_cache: {
530+ if ( ! hasChanged ) {
531+ break clear_next_cache;
532+ }
503533
504- if ( Buffer . compare ( rawIconCssCodeBuffer , currentCode ) === 0 ) {
505- return ;
506- }
534+ const nextCacheDir = pathJoin ( projectDirPath , ".next" , "cache" ) ;
535+
536+ if ( ! fs . existsSync ( nextCacheDir ) ) {
537+ break clear_next_cache;
538+ }
539+
540+ await rm ( nextCacheDir , { "recursive" : true , "force" : true } ) ;
541+ }
507542
508- onConfirmedChange ( ) ;
543+ copy_used_dsfr_icons_to_public: {
544+ if ( ! hasChanged ) {
545+ break copy_used_dsfr_icons_to_public;
546+ }
509547
510- writeFile ( cssFilePath , rawIconCssCodeBuffer ) ;
511- } ) ;
548+ if ( dsfrDistInPublicDirPath === undefined || dsfrDistInNodeModulesDirPath === undefined ) {
549+ break copy_used_dsfr_icons_to_public;
550+ }
551+
552+ await Promise . all (
553+ usedIcons
554+ . filter ( icon => icon . prefix === "fr-icon-" )
555+ . map ( ( { svgRelativePath } ) =>
556+ ( [ dsfrDistInNodeModulesDirPath , dsfrDistInPublicDirPath ] as const ) . map (
557+ baseDirPath =>
558+ pathJoin ( baseDirPath , utilityIconsRelativeDirPath , svgRelativePath )
559+ )
560+ )
561+ . map ( ( [ srcFilePath , destFilePath ] ) => cp ( srcFilePath , destFilePath ) )
562+ ) ;
563+ }
512564}
513565
514566if ( require . main === module ) {
0 commit comments