Skip to content

Commit

Permalink
Emit TS types for variables extracted from sass
Browse files Browse the repository at this point in the history
  • Loading branch information
weltenwort committed Mar 20, 2019
1 parent e7f9a00 commit 72a71e0
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"test-docker": "docker pull $npm_package_docker_image && docker run --rm -i -e GIT_COMMITTER_NAME=test -e GIT_COMMITTER_EMAIL=test --user=$(id -u):$(id -g) -e HOME=/tmp -v $(pwd):/app -w /app $npm_package_docker_image bash -c 'npm config set spin false && /opt/yarn*/bin/yarn && npm run test && npm run build'",
"sync-docs": "node ./scripts/docs-sync.js",
"build-docs": "webpack --config=src-docs/webpack.config.js",
"build": "yarn extract-i18n-strings && node ./scripts/compile-clean.js && node ./scripts/compile-eui.js && node ./scripts/compile-scss.js",
"build": "yarn extract-i18n-strings && node ./scripts/compile-clean.js && node ./scripts/compile-eui.js && node ./scripts/compile-scss.js $npm_package_name",
"extract-i18n-strings": "node ./scripts/babel/fetch-i18n-strings",
"lint": "yarn lint-es && yarn lint-ts && yarn lint-sass && yarn lint-framer",
"lint-fix": "yarn lint-es-fix && yarn lint-ts-fix",
Expand Down
40 changes: 35 additions & 5 deletions scripts/compile-scss.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const globModule = require('glob');
const chalk = require('chalk');
const postcss = require('postcss');
const sassExtract = require('sass-extract');
const { deriveSassVariableTypes } = require('./derive-sass-variable-types');
const sassExtractJsPlugin = require('./sass-extract-js-plugin');

const postcssConfiguration = require('../src-docs/postcss.config.js');
Expand All @@ -22,7 +23,11 @@ const postcssConfigurationWithMinification = {
],
};

async function compileScssFiles(sourcePattern, destinationDirectory) {
async function compileScssFiles(
sourcePattern,
destinationDirectory,
packageName
) {
try {
await mkdir(destinationDirectory);
} catch (err) {
Expand All @@ -42,7 +47,9 @@ async function compileScssFiles(sourcePattern, destinationDirectory) {
const outputFilenames = await compileScssFile(
inputFilename,
path.join(destinationDirectory, `eui_${name}.css`),
path.join(destinationDirectory, `eui_${name}.json`)
path.join(destinationDirectory, `eui_${name}.json`),
path.join(destinationDirectory, `eui_${name}.json.d.ts`),
packageName
);

console.log(
Expand All @@ -64,7 +71,9 @@ async function compileScssFiles(sourcePattern, destinationDirectory) {
async function compileScssFile(
inputFilename,
outputCssFilename,
outputVarsFilename
outputVarsFilename,
outputVarTypesFilename,
packageName
) {
const outputCssMinifiedFilename = outputCssFilename.replace(
/\.css$/,
Expand All @@ -81,6 +90,12 @@ async function compileScssFile(
}
);

const extractedVarTypes = await deriveSassVariableTypes(
extractedVars,
`${packageName}/${outputVarsFilename}`,
outputVarTypesFilename
);

const { css: postprocessedCss } = await postcss(postcssConfiguration).process(
renderedCss,
{
Expand All @@ -100,9 +115,24 @@ async function compileScssFile(
writeFile(outputCssFilename, postprocessedCss),
writeFile(outputCssMinifiedFilename, postprocessedMinifiedCss),
writeFile(outputVarsFilename, JSON.stringify(extractedVars, undefined, 2)),
writeFile(outputVarTypesFilename, extractedVarTypes),
]);

return [outputCssFilename, outputVarsFilename];
return [
outputCssFilename,
outputCssMinifiedFilename,
outputVarsFilename,
outputVarTypesFilename,
];
}

compileScssFiles(path.join('src', 'theme_*.scss'), 'dist');
if (require.main === module) {
const [nodeBin, scriptName, euiPackageName] = process.argv;

if (process.argv.length < 3) {
console.log(chalk`{bold Usage:} ${nodeBin} ${scriptName} eui-package-name`);
process.exit(1);
}

compileScssFiles(path.join('src', 'theme_*.scss'), 'dist', euiPackageName);
}
75 changes: 75 additions & 0 deletions scripts/derive-sass-variable-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const ts = require('typescript');
const prettier = require('prettier');

async function deriveSassVariableTypes(
extractedVars,
extractedVarsModuleName,
extractedVarTypesFilename
) {
const extractedVarsModuleDeclaration = ts.createModuleDeclaration(
undefined,
[ts.createModifier(ts.SyntaxKind.DeclareKeyword)],
ts.createStringLiteral(extractedVarsModuleName),
ts.createModuleBlock([
ts.createVariableStatement(
undefined,
ts.createVariableDeclarationList(
[
ts.createVariableDeclaration(
'sassVariables',
deriveValueType(extractedVars)
),
],
ts.NodeFlags.Const
)
),
ts.createExportAssignment(
undefined,
undefined,
undefined,
ts.createIdentifier('sassVariables')
),
]),
ts.NodeFlags.None
);

const moduleSource = ts
.createPrinter({ newLine: ts.NewLineKind.LineFeed })
.printNode(
ts.EmitHint.Unspecified,
extractedVarsModuleDeclaration,
ts.createSourceFile(extractedVarTypesFilename, '', ts.ScriptTarget.Latest)
);

const prettierOptions = await prettier.resolveConfig(extractedVarTypesFilename);
const prettifiedModuleSource = prettier.format(moduleSource, prettierOptions);

return prettifiedModuleSource;
}

function deriveValueType(extractedValue) {
switch (typeof extractedValue) {
case 'object':
return ts.createTypeLiteralNode(
Object.keys(extractedValue).map(key =>
ts.createPropertySignature(
undefined,
ts.createStringLiteral(key),
undefined,
deriveValueType(extractedValue[key]),
undefined
)
)
);
case 'string':
return ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
case 'number':
return ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
default:
return ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
}
}

module.exports = {
deriveSassVariableTypes,
};

0 comments on commit 72a71e0

Please sign in to comment.