Skip to content

Commit

Permalink
fix: typescript, sdv4 migration
Browse files Browse the repository at this point in the history
  • Loading branch information
bennypowers committed Aug 22, 2024
1 parent e42b483 commit ca145ce
Show file tree
Hide file tree
Showing 29 changed files with 197 additions and 202 deletions.
58 changes: 33 additions & 25 deletions build.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
import YAML from 'yaml';
import StyleDictionary from 'style-dictionary';

import * as Formats from './lib/formats.js';
import * as Transforms from './lib/transforms.js';
import * as FileHeaders from './lib/file-header.js';
import * as TransformGroups from './lib/transform-groups.js';
import * as Actions from './lib/actions.js';
import * as Filters from './lib/filters.js';
import * as Preprocessors from './lib/preprocessors.js';
import * as Formats from './lib/formats.ts';
import * as Transforms from './lib/transforms.ts';
import * as FileHeaders from './lib/file-header.ts';
import * as TransformGroups from './lib/transform-groups.ts';
import * as Actions from './lib/actions.ts';
import * as Filters from './lib/filters.ts';
import * as Preprocessors from './lib/preprocessors.ts';

import { readFile } from 'node:fs/promises';

export async function build() {
const yamlPlatforms = await readFile(new URL('./platforms.yaml', import.meta.url), 'utf-8');
const platforms = YAML.parse(yamlPlatforms as unknown as string);
const platformsUrl = new URL('./platforms.yaml', import.meta.url);
const yamlPlatforms = await readFile(platformsUrl, 'utf-8');
if (typeof yamlPlatforms !== 'string') {
console.log(yamlPlatforms);
throw new Error('Bad Platforms');
}

const sd = new StyleDictionary();
const platforms = YAML.parse(yamlPlatforms);

sd.registerParser({
name: 'yaml',
pattern: /\.ya?ml$/,
parser: ({ contents }) => YAML.parse(contents),
const sd = new StyleDictionary({
hooks: {
parsers: {
yaml: {
pattern: /\.ya?ml$/,
parser: ({ contents }) => YAML.parse(contents),
}
}
},
parsers: [ 'yaml', ],
preprocessors: ['split-colors'],
source: [
'tokens/**/*.yml',
'tokens/**/*.yaml',
],
platforms,
log: {
verbosity: 'verbose',
}
});

sd.registerPreprocessor(Preprocessors.splitColors)
Expand Down Expand Up @@ -57,17 +76,6 @@ export async function build() {
sd.registerAction(Actions.writeVSIXManifest)
sd.registerAction(Actions.descriptionFile)

await sd.extend({
source: [
'tokens/**/*.{yaml,yml}',
],
parsers: [
'yaml',
],
preprocessors: ['split-colors'],
platforms,
})

await sd.hasInitialized;
await sd.buildAllPlatforms();
}
Expand Down
6 changes: 0 additions & 6 deletions jsconfig.json

This file was deleted.

103 changes: 53 additions & 50 deletions lib/actions.js → lib/actions.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import {
readFileSync,
copyFileSync,
mkdirSync,
rmSync,
writeFileSync,
rmdirSync,
readdirSync,
} from 'node:fs';
readFile,
copyFile,
mkdir,
writeFile,
rmdir,
rm,
readdir,
} from 'node:fs/promises';

import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

/** @typedef {import('style-dictionary').Named<import('style-dictionary').Action>} Action */
import type { Token } from 'style-dictionary'
import type { Action } from 'style-dictionary/types';

const rel = path => new URL(path, import.meta.url);
const rel = (path: string) => new URL(path, import.meta.url);
const DOCS_STYLES_IN = fileURLToPath(rel('../docs/styles.css'));
const DOCS_STYLES_OUT = fileURLToPath(rel('../build/styles.css'));
const TYPES_IN = fileURLToPath(rel('./types.ts'));
Expand All @@ -33,74 +35,72 @@ const TOKENS_DECL_URLS = [
rel('../js/tokens.d.cts')
];

const { version } = JSON.parse(readFileSync(PACKAGE_JSON_URL, 'utf8'));
const { version } = JSON.parse(
await readFile(PACKAGE_JSON_URL, 'utf-8') as unknown as string
);

/**
* Copy web assets to build dir
* @type {Action}
*/
export const copyAssets = {
export const copyAssets: Action = {
name: 'copy-assets',
do() {
copyFileSync(DOCS_STYLES_IN, DOCS_STYLES_OUT);
mkdirSync(ASSETS_IN_DIR, { recursive: true });
mkdirSync(ASSETS_OUT_DIR, { recursive: true });
for (const asset of readdirSync(ASSETS_IN_DIR)) {
copyFileSync(
async do() {
await copyFile(DOCS_STYLES_IN, DOCS_STYLES_OUT);
await mkdir(ASSETS_IN_DIR, { recursive: true });
await mkdir(ASSETS_OUT_DIR, { recursive: true });
for (const asset of await readdir(ASSETS_IN_DIR)) {
await copyFile(
new URL(`./${asset}`, ASSETS_IN_DIR.href),
new URL(`./${asset}`, ASSETS_OUT_DIR.href),
);
}
},
undo() {
rmdirSync(ASSETS_OUT_DIR, { force: true });
rmSync(DOCS_STYLES_OUT, { force: true });
async undo() {
await rmdir(ASSETS_OUT_DIR, { recursive: true });
await rm(DOCS_STYLES_OUT, { force: true });
}
};

/**
* Copy base TS types
* @type {Action}
*/
export const copyTypes = {
export const copyTypes: Action = {
name: 'copyTypes',
do() {
copyFileSync(TYPES_IN, TYPES_OUT);
async do() {
await copyFile(TYPES_IN, TYPES_OUT);
},
undo() {
rmSync(TYPES_OUT, { force: true });
async undo() {
await rm(TYPES_OUT, { force: true });
}
};

/**
* Write declaration file for JS token map
* @type {Action}
*/
export const writeEsMapDeclaration = {
export const writeEsMapDeclaration: Action = {
name: 'writeEsMapDeclaration',
do() {
async do() {
for (const url of TOKENS_DECL_URLS) {
writeFileSync(url, TOKENS_DECL_CONTENT, 'utf8');
await writeFile(url, TOKENS_DECL_CONTENT, 'utf8');
}
},
undo() {
async undo() {
for (const url of TOKENS_DECL_URLS) {
rmSync(url);
await rm(url);
}
}
};

/**
* Write VSCode package manifest
* @type {Action}
*/
export const writeVSIXManifest = {
export const writeVSIXManifest: Action = {
name: 'writeVSIXManifest',
do() {
mkdirSync(dirname(fileURLToPath(VSIX_MANIFEST_URL)), { recursive: true });
copyFileSync(LICENSE_URL, VSCODE_LICENSE_URL);
copyFileSync(README_URL, VSCODE_README_URL);
writeFileSync(VSIX_MANIFEST_URL, JSON.stringify({
async do() {
await mkdir(dirname(fileURLToPath(VSIX_MANIFEST_URL)), { recursive: true });
await copyFile(LICENSE_URL, VSCODE_LICENSE_URL);
await copyFile(README_URL, VSCODE_README_URL);
await writeFile(VSIX_MANIFEST_URL, JSON.stringify({
name: 'red-hat-design-tokens',
version,
publisher: 'Red Hat UX',
Expand All @@ -125,14 +125,14 @@ export const writeVSIXManifest = {
},
}, null, 2), 'utf8');
},
undo() {
rmSync(VSIX_MANIFEST_URL);
rmSync(VSCODE_LICENSE_URL);
rmSync(VSCODE_README_URL);
async undo() {
await rm(VSIX_MANIFEST_URL);
await rm(VSCODE_LICENSE_URL);
await rm(VSCODE_README_URL);
}
};

function getFilePathGuess(collection) {
function getFilePathGuess(collection: Token) {
return Object.values(collection).reduce((path, val) =>
path || typeof val !== 'object' ? path
: '$value' in val ? val.filePath
Expand All @@ -144,7 +144,7 @@ function getDescription(collection) {
filePath = getFilePathGuess(collection),
descriptionFile,
} = collection.$extensions[EXT_KEY];
return readFileSync(join(process.cwd(), dirname(filePath), descriptionFile), 'utf-8');
return readFile(join(process.cwd(), dirname(filePath), descriptionFile), 'utf-8');
}

function writeDescription(parent) {
Expand All @@ -163,9 +163,12 @@ function writeDescription(parent) {

export const descriptionFile = {
name: 'descriptionFile',
do() {
const json = JSON.parse(readFileSync(OUTPUT_JSON_URL, 'utf8'));
async do() {
const json = JSON.parse(await readFile(OUTPUT_JSON_URL, 'utf8') as unknown as string);
writeDescription(json);
writeFileSync(OUTPUT_JSON_URL, JSON.stringify(json, null, 2));
await writeFile(OUTPUT_JSON_URL, JSON.stringify(json, null, 2));
},
async undo() {
await rm(OUTPUT_JSON_URL)
}
};
File renamed without changes.
5 changes: 3 additions & 2 deletions lib/filters.js → lib/filters.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Filter } from "style-dictionary/types";

/**
* Match tokens which contain `-color-` in the css variable name
* @type {import('style-dictionary').Named<import('style-dictionary').Filter>}
*/
export const isColor = {
export const isColor: Filter = {
name: 'isColor',
filter(token) {
return Object.values(token.attributes).includes('color');
Expand Down
5 changes: 0 additions & 5 deletions lib/formats.js

This file was deleted.

5 changes: 5 additions & 0 deletions lib/formats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './formats/lit.ts';
export * from './formats/map.ts';
export * from './formats/modules.ts';
export * from './formats/docs.ts';
export * from './formats/editor.ts';
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/formats/editor.js → lib/formats/editor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isColor } from '../predicates.js';
import { isColor } from '../predicates.ts';

/** @typedef {import('style-dictionary').Format} Format */

Expand Down
4 changes: 2 additions & 2 deletions lib/formats/lit.js → lib/formats/lit.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Format } from 'style-dictionary/types'
import { fileHeader, formattedVariables } from 'style-dictionary/utils'

/**
* Lit CSS object
* @type {import('style-dictionary').Format}
* @example ```js
* import { resetStyles } from '@rhds/tokens/reset.css.js';
*
Expand All @@ -12,7 +12,7 @@ import { fileHeader, formattedVariables } from 'style-dictionary/utils'
* }
* ```
*/
export const litCss = {
export const litCss: Format = {
name: 'css/lit',
format: ({ file, dictionary, options }) =>
`${fileHeader({ file })}
Expand Down
File renamed without changes.
37 changes: 23 additions & 14 deletions lib/formats/modules.js → lib/formats/modules.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import * as Predicates from '../predicates.js';
import type { Format } from 'style-dictionary/types';
import type { Token } from 'style-dictionary';

import * as Predicates from '../predicates.ts';

import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { colorFormats } from '../transforms.js';
import { colorFormats } from '../transforms.ts';
import { fileHeader } from 'style-dictionary/utils'

function deserializeShadow(x) {
const [offsetX, offsetY, blur, spread, color] = x.$value.split(' ');
return JSON.stringify({ offsetX, offsetY, blur, spread, color });
function deserializeShadow(x: Token) {
if (typeof x.$value === 'object')
return JSON.stringify(x.$value);
else {
const [offsetX, offsetY, blur, spread, color] = x.$value.split(' ');
return JSON.stringify({ offsetX, offsetY, blur, spread, color });
}
}

const capitalize = x => `${x.at(0).toUpperCase()}${x.slice(1)}`;
const capitalize = (x: string) => `${x.at(0).toUpperCase()}${x.slice(1)}`;

function colorRef(x) {
const r = JSON.stringify(colorFormats.transformer({ ...x }));
function colorRef(x: Token) {
const r = JSON.stringify(colorFormats.transform({ ...x }));
return r;
}

function mediaRef(x) {
function mediaRef(x: Token) {
const values = [];
const stringified = JSON.stringify(x.original.$value, (_, value) => {
const [, inner] = value?.match?.(/^\{(.*)\}$/) ?? [];
Expand All @@ -34,12 +42,11 @@ function mediaRef(x) {

/**
* Per-category javascript modules
* @type {import('style-dictionary').Format}
* @example ```js
* import { Red300 } from '@rhds/tokens/color.js';
* ```
* import { Red300 } from '@rhds/tokens/color.js';
* ```
*/
export const modules = {
export const modules: Format = {
name: 'javascript/modules',
format({ file, dictionary, platform }) {
const categories = new Set(dictionary.allTokens.map(x => x.attributes.category));
Expand Down Expand Up @@ -67,9 +74,11 @@ export const modules = {
].join('\n');
writeFileSync(outpath, contents, 'utf8');
}
return [
const content = [
fileHeader({ file }),
...Array.from(categories, x => `export * from './${x}.js';`),
].join('\n');
console.log(content)
return content
},
};
File renamed without changes.
Loading

0 comments on commit ca145ce

Please sign in to comment.