import * as fse from 'fs-extra' ; import * as path from 'path' ; import * as atImport from 'postcss-import' ; import postcss from 'postcss' ; import { pick } from 'lodash' ; import { getNameFromPath } from '../utils/common' ; import { getThemeVarsPlugin } from '../plugins/postcss/getThemeVarsPlugin' ; interface ThemesDataType { [ themeKey ] : ThemeVarsType ; } interface ThemeVarsType { [ cssVariable ] : string ; } let __themesData__ = { } ; const cacheUrl = path . resolve ( 'node_modules' , '.cache' , 'themes_data.json' ) ; /**
 * 组合 themesData 对象字符串
 */ const getThemesDataStr = ( themesData , defaultName ) => { const themesDataStr = Object . keys ( themesData ) . filter ( themeKey => themeKey !== defaultName ) . map ( ( themeKey ) => { const cssVars = themesData [ themeKey ] ; return `'${ themeKey }': ':root {${ Object . entries ( cssVars ) . map ( ( [ k , v ] ) => `--${ k }: ${ v }` ) . join ( ';' ) }}'` ; } ) . join ( ',' ) ; return `{${ themesDataStr }}` ; } ; param { string } filePath const getThemeVars = async ( filePath ) : Promise < ThemeVarsType > => { const themeVars = { } ; const css = fse . readFileSync ( filePath , 'utf8' ) ; await postcss ( [ atImport ( ) , getThemeVarsPlugin ( { themeVars } ) ] as any ) . process ( css , { from : filePath } ) ; return themeVars ; } ; param { String [ ] } themesPathList param { String } defaultTheme const parseThemesData = async ( themesPathList , defaultTheme ) => { const data = { } as ThemesDataType ; const newData = { } as ThemesDataType ; const varsList = [ ] ; const task = async ( file ) => { const themeName = getNameFromPath ( file ) ; const value = await getThemeVars ( file ) ; data [ themeName ] = value ; } ; await Promise . all ( themesPathList . map ( task ) ) ; const themesList = Object . keys ( data ) . filter ( name => name !== defaultTheme ) ; const defaultData = data [ defaultTheme ] ; Object . keys ( defaultData ) . forEach ( varName => { themesList . forEach ( theme => { if ( defaultData [ varName ] !== data [ theme ] [ varName ] ) { varsList . push ( varName ) ; } } ) ; } ) ; newData [ defaultTheme ] = data [ defaultTheme ] ; themesList . forEach ( theme => { newData [ theme ] = pick ( data [ theme ] , varsList ) ; } ) ; return newData ; } ; param { ThemesDataType } newData param { Boolean } persist const setThemesData = ( newData , persist = false ) => { __themesData__ = newData ; if ( persist ) fse . outputFileSync ( cacheUrl , JSON . stringify ( newData ) ) ; } ; return { ThemesDataType } const getThemesData = ( ) : ThemesDataType => { if ( fse . existsSync ( cacheUrl ) ) { const fileString = fse . readFileSync ( cacheUrl , 'utf8' ) ; const data = JSON . parse ( fileString ) ; if ( data ) return data ; } return __themesData__ ; } ; export { parseThemesData , getThemesData , getThemesDataStr , setThemesData , ThemeVarsType } ;