UNPKG

@cssninja/bulma-css-vars

Version:
211 lines (205 loc) 8.95 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import * as path from 'path'; import { existsSync } from 'fs'; import { defaultOptions } from './default-options'; import { getUsedVariables } from './find-used-vars'; import { ColorGenerator } from './color-updater'; import { strValFromColorDef, stringToHsl } from './bulma-color-tools'; import { getAbsoluteFileName, exists, fileStartsWith, writeFile, } from './fs-helper'; import { getCssFallbacks } from './css-post-processor'; import { compileSass } from './compile-sass'; const configFileName = 'bulma-css-vars.config.js'; const cjsConfigFileName = 'bulma-css-vars.config.cjs'; const mainSassFileName = 'src/main.scss'; const configFilePathAtCwd = (cwd) => path.join(cwd, configFileName); const cjsConfigFilePathAtCwd = (cwd) => path.join(cwd, cjsConfigFileName); const mainSassFilePathAtCwd = (cwd) => path.join(cwd, mainSassFileName); function validateOptions(cwd) { return __awaiter(this, void 0, void 0, function* () { const configFilePath = configFilePathAtCwd(cwd); const cjsConfigFilePath = cjsConfigFilePathAtCwd(cwd); let loadedOptions = {}; if (existsSync(cjsConfigFilePath)) { try { loadedOptions = yield import(cjsConfigFilePath).then(m => m.default || m); } catch (err) { throw new Error(`Unable to parse configuration file at '${cjsConfigFilePath}': ${err}`); } } else if (existsSync(configFilePath)) { try { loadedOptions = yield import(configFilePath).then(m => m.default || m); } catch (err) { throw new Error(`Unable to parse cjs configuration file at '${configFilePath}': ${err}`); } } else { throw new Error(`Required config file '${configFileName}' was not found at ${configFilePath}`); } const options = Object.assign(Object.assign({}, defaultOptions), loadedOptions); if (options.sassEntryFile === null) { throw new Error('[Bulma CSS Vars] cannot create definitions, entry sass file does not exist in config'); } if (options.transition && typeof options.transition !== 'string') { throw new Error(`[Bulma CSS Vars] if 'transition' is declared, it must be a string`); } // js output file const jsOutputFile = getAbsoluteFileName(options.jsOutputFile, cwd); // sass output file const sassOutputFile = getAbsoluteFileName(options.sassOutputFile, cwd); // sass output file const fallbackOutputFile = options.cssFallbackOutputFile ? getAbsoluteFileName(options.cssFallbackOutputFile, cwd) : null; // web with globals const globalWebVar = options.globalWebVar; // entry sass file const sassEntryFile = getAbsoluteFileName(options.sassEntryFile, cwd); if (jsOutputFile.endsWith('.ts') && globalWebVar) { throw new Error('TypeScript output with direct web usage is not possible - file has to be processed anyway!'); } if (!(yield exists(sassEntryFile))) { throw new Error(`[Bulma CSS Vars] cannot create definitions, entry sass file does not exist in file system at ${sassEntryFile}`); } return { options, jsOutputFile, sassOutputFile, fallbackOutputFile, globalWebVar, sassEntryFile, }; }); } export function runCli(cwd) { return __awaiter(this, void 0, void 0, function* () { const { options, fallbackOutputFile, globalWebVar, jsOutputFile, sassEntryFile, sassOutputFile, } = yield validateOptions(cwd); // colorDefs const colorDefs = options.colorDefs; const colorCallSetFromColorDef = Object.assign({}, ...Object.entries(colorDefs).map(([colorName, _colorCallDef]) => { return { [colorName]: { calls: [], }, }; })); const provisionalUpdater = new ColorGenerator(colorCallSetFromColorDef); const sassVarsContentBase = provisionalUpdater.createWritableSassFileOnlySassBaseVariables(); // create empty sass vars output file if it does not exist yet if (!(yield exists(sassOutputFile)) || !(yield fileStartsWith(sassOutputFile, sassVarsContentBase))) { yield writeFile(sassOutputFile, sassVarsContentBase); } // render sass const renderedCss = compileSass(sassEntryFile); // run find-used-vars to get used vars const colorNames = Object.keys(colorDefs); const usedVars = getUsedVariables(renderedCss, colorNames); const usedVarsWithColors = Object.assign({}, ...Object.entries(usedVars).map(([colorName, colorDef]) => { const value = stringToHsl(strValFromColorDef(colorDefs[colorName], colorName)); return { [colorName]: Object.assign(Object.assign({}, colorDef), { value }) }; })); // run generate-vars to have sass information const generator = new ColorGenerator(usedVarsWithColors); const sassVarsContent = generator.createWritableSassFile(); if (fallbackOutputFile) { const allColorVars = generator.getAllVars(); // fill in fallback values const cssFallbackContent = getCssFallbacks(renderedCss, allColorVars, options.transition); if (cssFallbackContent) { yield writeFile(fallbackOutputFile, cssFallbackContent); console.log(`Updated ${fallbackOutputFile}`); } } // write sass vars output file yield writeFile(sassOutputFile, sassVarsContent); console.log(`Updated ${sassOutputFile}`); // write js output file let jsOutputContent; if (jsOutputFile.endsWith('.ts')) { // write ts file jsOutputContent = ` export type ColorFn = | 'rgba' | 'adjusthue' | 'saturate' | 'desaturate' | 'lighten' | 'darken' | 'color-invert' | 'dark-color' | 'light-color' export interface ColorFnCall { fn: ColorFn fnArg: string | null composeArg: ColorFnCall | null } export interface ColorCallSet { [color: string]: { calls: ColorFnCall[], } } export const bulmaCssVariablesDefs: ColorCallSet = ${JSON.stringify(usedVars, null, 2)} `; } else if (globalWebVar) { // write js file jsOutputContent = ` Object.defineProperty(window, 'bulmaCssVarsDef', { enumerable: true, value: ${JSON.stringify(usedVars)} } ) `; } else { // write js file jsOutputContent = ` module.exports = ${JSON.stringify({ bulmaCssVariablesDefs: usedVars }, null, 2)} `; } const fullJsOutputFile = jsOutputFile.endsWith('.ts') || jsOutputFile.endsWith('.js') ? jsOutputFile : `${jsOutputFile}.js`; yield writeFile(fullJsOutputFile, jsOutputContent); console.log(`Updated ${jsOutputFile}`); }); } const defaultConfigContent = `const appColors = { primary: '#5229fa', } module.exports = { jsOutputFile: 'src/bulma-generated/bulma-colors.js', sassOutputFile: 'src/bulma-generated/generated-bulma-vars.sass', cssFallbackOutputFile: 'src/bulma-generated/generated-fallback.css', colorDefs: appColors, sassEntryFile: 'src/main.scss', transition: '0.5s ease' } `; const defaultMainScssContent = `@import './bulma-generated/generated-fallback.css'; @import './bulma-generated/generated-bulma-vars.sass'; @import '../node_modules/bulma-css-vars/bulma-cv-lib'; `; export function runCliInit(cwd) { return __awaiter(this, void 0, void 0, function* () { const configFileNamePath = configFilePathAtCwd(cwd); if (yield exists(configFileNamePath)) { console.log(`bulma-css-vars Config file already exists at ${configFileNamePath}, exiting.`); process.exit(1); } yield writeFile(configFileNamePath, defaultConfigContent); const mainSassFilePath = mainSassFilePathAtCwd(cwd); if (!(yield exists(mainSassFilePath))) { yield writeFile(mainSassFilePath, defaultMainScssContent); } }); }