Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(cli): clean up tokens create code #3338

Draft
wants to merge 16 commits into
base: next
Choose a base branch
from
5 changes: 2 additions & 3 deletions packages/cli/bin/designsystemet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env node
import fs from 'node:fs/promises';
import path from 'node:path';
import { Argument, createCommand, program } from '@commander-js/extra-typings';
import chalk from 'chalk';
Expand All @@ -12,8 +11,8 @@ import migrations from '../src/migrations/index.js';
import { buildTokens } from '../src/tokens/build.js';
import { cliOptions, createTokens } from '../src/tokens/create.js';
import type { Theme } from '../src/tokens/types.js';
import { cleanDir } from '../src/tokens/utils.js';
import { writeTokens } from '../src/tokens/write.js';
import { cleanDir, readFile } from '../src/utils.js';
import { type CombinedConfigSchema, combinedConfigSchema, configFileSchema, mapPathToOptionName } from './config.js';
import { type OptionGetter, getCliOption, getDefaultCliOption, getSuppliedCliOption } from './options.js';

Expand Down Expand Up @@ -234,7 +233,7 @@ async function parseConfig(

let configFile: string;
try {
configFile = await fs.readFile(resolvedPath, { encoding: 'utf-8' });
configFile = await readFile(resolvedPath);
console.log(`Found config file: ${chalk.green(resolvedPath)}`);
} catch (err) {
if (err instanceof Error) {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
"test:tokens-create-and-build-config": "yarn test:tokens-create-config && yarn test:tokens-build",
"test": "yarn test:tokens-create-and-build-options && yarn test:tokens-create-and-build-config",
"internal:tokens-create": "yarn designsystemet tokens create --config ./internal.config.json",
"update:template": "tsx ./src/tokens/template.ts",
"update:design-tokens": "yarn internal:tokens-create && tsx ./src/scripts/copy-internal-tokens.ts"
"update:template": "tsx ./src/scripts/update-template.ts",
"update:design-tokens": "yarn internal:tokens-create && tsx ./src/scripts/update-design-tokens.ts"
},
"dependencies": {
"@commander-js/extra-typings": "^13.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/migrations/codemods/css/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'node:fs';
import glob from 'fast-glob';
import type { AcceptedPlugin } from 'postcss';
import postcss from 'postcss';
import { readFile } from '../../../utils.js';

type CssCodemodProps = {
plugins: AcceptedPlugin[];
Expand All @@ -24,7 +25,7 @@ export const runCssCodemod = async ({ plugins = [], globPattern = './**/*.css' }
// console.log(`Skipping ${file}`);
return;
}
const contents = fs.readFileSync(file).toString();
const contents = readFile(file).toString();
const result = await processor.process(contents, { from: file });

fs.writeFileSync(file, result.css);
Expand Down
40 changes: 0 additions & 40 deletions packages/cli/src/scripts/copy-internal-tokens.ts

This file was deleted.

35 changes: 35 additions & 0 deletions packages/cli/src/scripts/update-design-tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import path from 'node:path';
import { cp } from '../utils.js';

const DIRNAME: string = import.meta.dirname || __dirname;

const TARGET = path.join(DIRNAME, '../../../../design-tokens');
const INTERNAL = path.join(DIRNAME, '../../internal/design-tokens');

async function copyFiles() {
console.log('📁 Copying design tokens');
await cp(path.join(INTERNAL, 'primitives/modes/color-scheme'), path.join(TARGET, 'primitives/modes/color-scheme'));

await cp(path.join(INTERNAL, 'primitives/modes/size'), path.join(TARGET, 'primitives/modes/size'));

// Not copying secondary typography due to unsupported secondary typography tokens in CLI
await cp(
path.join(INTERNAL, 'primitives/modes/typography/primary'),
path.join(TARGET, 'primitives/modes/typography/primary'),
);

await cp(
path.join(INTERNAL, 'primitives/modes/typography/size'),
path.join(TARGET, 'primitives/modes/typography/size'),
);

await cp(path.join(INTERNAL, 'primitives/globals.json'), path.join(TARGET, 'primitives/globals.json'));

await cp(path.join(INTERNAL, 'semantic'), path.join(TARGET, 'semantic'));

await cp(path.join(INTERNAL, 'themes'), path.join(TARGET, 'themes'));

console.log('✅ Finished copying design tokens');
}

await copyFiles();
151 changes: 151 additions & 0 deletions packages/cli/src/scripts/update-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import path from 'node:path';
import chalk from 'chalk';
import * as R from 'ramda';
import digdirTypographyJson from '../../../../design-tokens/primitives/modes/typography/primary/digdir.json' with {
type: 'json',
};
import semanticColorJson from '../../../../design-tokens/semantic/color.json' with { type: 'json' };
import accentColorCategoryJson from '../../../../design-tokens/semantic/modes/main-color/accent.json' with {
type: 'json',
};
import digdirThemeJson from '../../../../design-tokens/themes/digdir.json' with { type: 'json' };
import { cleanDir, cp, mkdir, writeFile } from '../utils.js';

const DIRNAME: string = import.meta.dirname || __dirname;

const SOURCE_FILES_PATH = path.join(DIRNAME, '../../../../design-tokens');
const TEMPLATE_FILES_PATH = path.join(DIRNAME, '../tokens/template/design-tokens');

const argsFromToPaths = (path_: string): [string, string] => [
path.join(SOURCE_FILES_PATH, path_),
path.join(TEMPLATE_FILES_PATH, path_),
];

export const updateTemplates = async () => {
// Clean template files
await cleanDir(TEMPLATE_FILES_PATH);

// Copy default files
await cp(...argsFromToPaths('primitives/globals.json'));
await cp(...argsFromToPaths('primitives/modes/size'));
await cp(...argsFromToPaths('primitives/modes/typography/size'));
await cp(...argsFromToPaths('semantic/style.json'));

/*
* Create template files
*/

// primitives/modes/typeography/<theme>.json
const typographyTemplate = R.set(
R.lensPath(['digdir', 'font-family', '$value']),
'<font-family>',
digdirTypographyJson,
);
const typographyDir = path.join(TEMPLATE_FILES_PATH, 'primitives/modes/typography/');
await mkdir(typographyDir);
await writeFile(
path.join(typographyDir, 'typography-template.json'),
JSON.stringify(typographyTemplate, null, 2).replaceAll('digdir', '<theme>'),
);

// semantic/modes/<category>-color/<color>.json
const categoryColorTemplate = accentColorCategoryJson.color.main;
const categoryDir = path.join(TEMPLATE_FILES_PATH, 'semantic/modes');
await mkdir(categoryDir);
await writeFile(
path.join(categoryDir, 'color-template.json'),
JSON.stringify(categoryColorTemplate, null, 2).replaceAll('color.accent', 'color.<color>'),
);

// semantic/color.json
const colorBaseFile = {
...semanticColorJson,
// Remove custom colors as they are defined from by theme
color: R.omit(['accent', 'neutral', 'brand1', 'brand2', 'brand3'], semanticColorJson.color),
};
await writeFile(
path.join(TEMPLATE_FILES_PATH, `semantic/color-base-template.json`),
JSON.stringify(colorBaseFile, null, 2),
);

const semanticColorTemplate = semanticColorJson.color.accent;
await writeFile(
path.join(TEMPLATE_FILES_PATH, `semantic/color-template.json`),
JSON.stringify(semanticColorTemplate, null, 2).replaceAll('color.accent', 'color.<color>'),
);

// themes/<theme>.json
const themeBaseFile = {
color: {},
...R.omit(['color'], digdirThemeJson),
};

await mkdir(path.join(TEMPLATE_FILES_PATH, 'themes'));
await writeFile(
path.join(TEMPLATE_FILES_PATH, `themes/theme-base-template.json`),
JSON.stringify(themeBaseFile, null, 2).replaceAll('digdir', '<theme>'),
);

const themeColorTemplate = digdirThemeJson.color.accent;
await writeFile(
path.join(TEMPLATE_FILES_PATH, `themes/theme-template.json`),
JSON.stringify(themeColorTemplate, null, 2).replaceAll('digdir.accent', '<theme>.<color>'),
);

// WIP
// // $themes.json
// const themesFile = await readFile(path.join(SOURCE_FILES_PATH, '$themes.json'), 'utf-8');
// const themesTemplate = (JSON.parse(themesFile) as ThemeObject[])
// .filter((themeobj) => {
// // Remove compact size
// if (R.toLower(themeobj.name) === 'compact' && R.toLower(themeobj.group || '') === 'size') {
// return false;
// }

// // Pick theme to use as template
// if (R.toLower(themeobj.name) !== 'digdir' && R.toLower(themeobj.group || '') === 'theme') {
// return false;
// }

// return true;
// })
// .map((themeobj) => {
// if (R.toLower(themeobj.name) === 'digdir') {
// return {
// ...themeobj,
// name: '<theme>',
// selectedTokenSets: {
// 'themes/<theme>': 'enabled',
// },
// };
// }
// return themeobj;
// });

// await writeFile(path.join(TEMPLATE_FILES_PATH, `$themes.json`), stringify(themesTemplate));

// // $metadata.json
// const metadataFile = await readFile(path.join(SOURCE_FILES_PATH, '$metadata.json'), 'utf-8');
// const tokenSetOrderTemplate = (JSON.parse(metadataFile) as { tokenSetOrder: string[] }).tokenSetOrder
// .filter((tokenSet) => {
// if (endsWithOneOf(['altinn', 'portal', 'uutilsynet'], tokenSet)) {
// return false;
// }
// return true;
// })
// .map((tokenSet) => {
// if (endsWithOneOf(['digdir'], tokenSet)) {
// return tokenSet.replace('/digdir', '/<theme>');
// }
// return tokenSet;
// });

// await writeFile(
// path.join(TEMPLATE_FILES_PATH, `$metadata.json`),
// stringify({ tokenSetOrder: tokenSetOrderTemplate }),
// );

console.log(chalk.green('Templates updated'));
};

await updateTemplates();
9 changes: 4 additions & 5 deletions packages/cli/src/tokens/build.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import fs from 'node:fs/promises';
import path from 'node:path';

import type { ThemeObject } from '@tokens-studio/types';
import chalk from 'chalk';
import * as R from 'ramda';
import StyleDictionary from 'style-dictionary';

import { cleanDir, readFile, writeFile } from '../utils.js';
import { configs, getConfigsForThemeDimensions } from './build/configs.js';
import {
type BuildConfig,
Expand All @@ -15,7 +15,6 @@ import {
} from './build/types.js';
import { makeEntryFile } from './build/utils/entryfile.js';
import { type ProcessedThemeObject, processThemeObject } from './build/utils/getMultidimensionalThemes.js';
import { cleanDir, writeFile } from './utils.js';

type Options = {
/** Design tokens path */
Expand Down Expand Up @@ -105,9 +104,9 @@ export async function buildTokens(options: Options): Promise<void> {
/*
* Build the themes
*/
const $themes = (
JSON.parse(await fs.readFile(path.resolve(`${tokensDir}/$themes.json`), 'utf-8')) as ThemeObject[]
).map(processThemeObject);
const $themes = (JSON.parse(await readFile(path.resolve(`${tokensDir}/$themes.json`))) as ThemeObject[]).map(
processThemeObject,
);

const relevant$themes = $themes
// We only use the 'medium' theme for the 'size' group
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/tokens/build/utils/entryfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import chalk from 'chalk';
import glob from 'fast-glob';
import fs from 'fs-extra';
import * as R from 'ramda';
import { writeFile } from '../../utils.js';
import { writeFile } from '../../../utils.js';

/**
* Defines a sort order for the sections of the entry CSS file.
Expand Down
Loading
Loading