Skip to content

Commit d09bbbb

Browse files
authored
Merge pull request #3397 from hashicorp/project-solar/phase-1/HDS-5668/07c_modes-validation
[Project Solar / Phase 1 / Engineering Follow-ups] Improve validation for `$modes`
2 parents 02683f7 + a8010a3 commit d09bbbb

File tree

3 files changed

+28
-66
lines changed

3 files changed

+28
-66
lines changed

packages/tokens/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@types/tinycolor2": "^1.4.6",
3838
"@typescript-eslint/eslint-plugin": "^8.18.1",
3939
"@typescript-eslint/parser": "^8.18.1",
40+
"chalk": "^5.4.1",
4041
"eslint": "^8.57.1",
4142
"fs-extra": "^11.2.0",
4243
"lodash-es": "^4.17.21",

packages/tokens/scripts/build.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import StyleDictionary from 'style-dictionary';
88
import type { DesignToken, PlatformConfig } from 'style-dictionary/types';
99

1010
import tinycolor from 'tinycolor2';
11+
import chalk from 'chalk';
1112

1213
import fs from 'fs-extra';
1314
import path from 'path';
@@ -36,27 +37,33 @@ const distFolder = path.resolve(__dirname, '../dist');
3637
for (const mode of modes) {
3738
StyleDictionary.registerPreprocessor({
3839
name: `replace-value-for-mode-${mode}`,
39-
preprocessor: (dictionary, _options) => {
40+
preprocessor: (dictionary, options) => {
41+
// we get the `buildPath` from the `PlatformConfig` option
42+
const buildPath = (options as any).buildPath;
4043
// recursively traverse token objects and replace the `$value` with the corresponding colocated `$modes` theme value
4144
// note: the `slice` is always an object (a token or a parent group)
42-
function replaceModes(slice: DesignToken) {
45+
function replaceModes(slice: DesignToken, tokenPath: string[]) {
4346
if (slice.$modes) {
4447
if (mode in slice.$modes) {
48+
// extra validation to catch instances where the `default` mode value is different from the `$value`
49+
if (mode === 'default' && slice.$modes[mode] !== slice.$value) {
50+
console.warn(`⚠️ ${chalk.yellow.bold('WARNING')} - Found themed 'default' token '{${path.join('.')}}' with value different than '$value' (\`${slice.$modes[mode]}\` instead of the expected \`${slice.$value}\`) - BuildPath: ${buildPath} - File: ${slice.filePath}`);
51+
}
4552
slice.$value = slice.$modes[mode];
4653
} else {
47-
// TODO! decide if we want to throw here (and test if it works, by removing a value from one of the test files) - see: https://hashicorp.atlassian.net/browse/HDS-5668
48-
console.error(`❌ ERROR - Found themed token without '${mode}' value:`, JSON.stringify(slice, null, 2));
54+
// we want to interrupt the execution of the script if one of the expected modes is missing
55+
throw new Error(`❌ ${chalk.red.bold('ERROR')} - Found themed token '{${path.join('.')}}' without '${mode}' value - BuildPath: ${buildPath} - File: ${slice.filePath} - Path: ${path.join('.')} - ${JSON.stringify(slice, null, 2)}`);
4956
}
5057
} else {
51-
Object.values(slice).forEach((value) => {
58+
Object.entries(slice).forEach(([key, value]) => {
5259
if (typeof value === 'object') {
53-
replaceModes(value);
60+
replaceModes(value, [...tokenPath, key]);
5461
}
5562
});
5663
}
5764
return slice;
5865
}
59-
return replaceModes(dictionary);
66+
return replaceModes(dictionary, []);
6067
},
6168
});
6269
}

pnpm-lock.yaml

Lines changed: 13 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)