import colors from 'colors'; import path from 'path'; import fs from 'fs'; import resolve from 'resolve'; const REGEXP_DEFAULT_PICKLIST_VALUE = /:default$/; function obtainCustomCssProperties(brandingJsonPath: string): any { if (fs.existsSync(brandingJsonPath) && fs.statSync(brandingJsonPath).isFile()) { const brandingJson = JSON.parse(fs.readFileSync(brandingJsonPath, 'utf-8')); return brandingJson.reduce((acc: any, entry: any) => { const { type, tokens, value, id, label } = entry; if (['Color', 'Font', 'Image', 'Picklist', 'Slider'].includes(type.name)) { let effectiveValue: string; if (type.name === 'Picklist') { const picklistValues = value.split(','); const defaultPicklistValue = picklistValues.find((v: string) => REGEXP_DEFAULT_PICKLIST_VALUE.test(v)); const defaultPicklistVal = defaultPicklistValue ? defaultPicklistValue.split(':') : []; if (defaultPicklistVal.length === 3 && defaultPicklistVal[2] === 'default') { effectiveValue = defaultPicklistVal[1]; } else { console.warn( `Skipped processing entry "${id}" of type "${type.name}": No default value defined in "${value}".` .yellow ); } } else { effectiveValue = value; } tokens.forEach((token: any) => { acc.push({ type, token, value: effectiveValue, id, label }); }); } else { console.warn(`Skipped processing entry "${id}": Unknown type "${type.name}".`.yellow); } return acc; }, []); } else { console.warn(colors.red(`Unable to process branding JSON: The file "${brandingJsonPath}" does not exist.`)); return []; } } function obtainCustomCssPropertiesString(brandingJsonPath: string): string { const cssProperties = obtainCustomCssProperties(brandingJsonPath).reduce((acc: string[], entry: any) => { const { type, token, value, id, label } = entry; let effectiveValue; if (type.name === 'Font') { effectiveValue = value ? `'${value}'` : null; } else { effectiveValue = value; } acc.push(`${token}: ${effectiveValue || "''"}; /* ID = ${id}, Type = ${type.name}, Label = ${label} */`); return acc; }, []); return `:root { ${cssProperties.join('\n ')} }\n`; } export async function buildBaseBranding(destination: string = '.storybook/assets/styles') { process.stdout.write(colors.blue('\tbuild base branding...')); const packageRootDir = process.cwd(); const storybookStylesDir = path.resolve(packageRootDir, destination); if (fs.existsSync(storybookStylesDir) && fs.statSync(storybookStylesDir).isDirectory()) { const baseBrandingJsonPath = resolve.sync('webruntime-branding-shared/templates/base-branding.json'); const webruntimeCssPath = path.resolve(storybookStylesDir, 'webruntime.css'); fs.writeFileSync(webruntimeCssPath, obtainCustomCssPropertiesString(baseBrandingJsonPath), 'utf-8'); console.log(`${webruntimeCssPath}`); } else { console.warn(colors.red(`Unable to apply branding JSON properties: The directory "${storybookStylesDir}" does not exist.`)); } }