From 7fcd4729e5faeab26ee25977f09916d3fb9ce6fb Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Thu, 17 Aug 2023 15:18:41 +0200 Subject: [PATCH 1/4] wip: support nested js output --- packages/plugin-js/src/index.ts | 30 +- packages/plugin-js/test/build.test.js | 21 ++ packages/plugin-js/test/nested/tokens.json | 46 +++ packages/plugin-js/test/nested/want.d.ts | 60 ++++ packages/plugin-js/test/nested/want.js | 314 +++++++++++++++++++++ packages/plugin-js/test/nested/want.json | 301 ++++++++++++++++++++ packages/utils/src/object.ts | 22 ++ 7 files changed, 790 insertions(+), 4 deletions(-) create mode 100644 packages/plugin-js/test/nested/tokens.json create mode 100644 packages/plugin-js/test/nested/want.d.ts create mode 100644 packages/plugin-js/test/nested/want.js create mode 100644 packages/plugin-js/test/nested/want.json diff --git a/packages/plugin-js/src/index.ts b/packages/plugin-js/src/index.ts index 5b19fe7a..3a7dfd7f 100644 --- a/packages/plugin-js/src/index.ts +++ b/packages/plugin-js/src/index.ts @@ -1,5 +1,5 @@ import type {BuildResult, Mode, ParsedToken, Plugin, Token} from '@cobalt-ui/core'; -import {cloneDeep, indent, objKey} from '@cobalt-ui/utils'; +import {cloneDeep, indent, objKey, set} from '@cobalt-ui/utils'; const JS_EXT_RE = /\.(mjs|js)$/i; const JSON_EXT_RE = /\.json$/i; @@ -16,6 +16,8 @@ export interface Options { meta?: boolean; /** modify values */ transform?: TransformFn; + /** nested or flat output (default: false) */ + deep?: boolean; } interface JSResult { @@ -48,8 +50,9 @@ const tokenTypes: Record = { }; /** serialize JS ref into string */ -export function serializeJS(value: unknown, options?: {comments?: Record; indentLv?: number}): string { +export function serializeJS(value: unknown, options?: {comments?: Record; commentPath?: string; indentLv?: number}): string { const comments = options?.comments || {}; + const commentPath = options?.commentPath ?? ''; const indentLv = options?.indentLv || 0; if (typeof value === 'string') return `'${value.replace(SINGLE_QUOTE_RE, "\\'")}'`; if (typeof value === 'number') return `${value}`; @@ -60,7 +63,16 @@ export function serializeJS(value: unknown, options?: {comments?: Record `${comments[k] ? `${indent(`/** ${comments[k]} */`, indentLv + 1)}\n` : ''}${indent(objKey(k), indentLv + 1)}: ${serializeJS(v, {indentLv: indentLv + 1})}`) + .map(([k, v]) => { + const nextCommentPath = commentPath === '' ? k : `${commentPath}.${k}`; + const comment = comments[nextCommentPath] ? `${indent(`/** ${comments[nextCommentPath]} */`, indentLv + 1)}\n` : ''; + + return `${comment}${indent(objKey(k), indentLv + 1)}: ${serializeJS(v, { + comments, + commentPath: nextCommentPath, + indentLv: indentLv + 1, + })}`; + }) .join(',\n')}, ${indent(`}${indentLv === 0 ? ';' : ''}`, indentLv)}`; throw new Error(`Could not serialize ${value}`); @@ -73,6 +85,16 @@ function defaultTransform(token: ParsedToken, mode?: string): (typeof token)['$v return {...(token.$value as typeof modeVal), ...modeVal}; } +function setToken(obj: Record, id: string, value: any, nest = false) { + if (nest) { + return set(obj, id, value); + } + + obj[id] = value; + + return obj; +} + export default function pluginJS(options?: Options): Plugin { if (options && options.js === false && options.json === false) throw new Error(`[plugin-js] Must output either JS or JSON. Received "js: false" and "json: false"`); @@ -106,7 +128,7 @@ export default function pluginJS(options?: Options): Plugin { const ts: TSResult = {tokens: [], meta: [], modes: []}; const transform = (typeof options?.transform === 'function' && options.transform) || defaultTransform; for (const token of tokens) { - js.tokens[token.id] = await transform(token); + setToken(js.tokens, token.id, await transform(token), options?.deep); if (buildTS) { const t = tokenTypes[token.$type]; ts.tokens.push(indent(`${objKey(token.id)}: ${t}['$value'];`, 1)); diff --git a/packages/plugin-js/test/build.test.js b/packages/plugin-js/test/build.test.js index 34f9640a..0751024d 100644 --- a/packages/plugin-js/test/build.test.js +++ b/packages/plugin-js/test/build.test.js @@ -24,4 +24,25 @@ describe('@cobalt-ui/plugin-js', () => { expect(fs.readFileSync(new URL('actual.json', cwd), 'utf8'), `${dir}: JSON`).toBe(fs.readFileSync(new URL('want.json', cwd), 'utf8')); }); }); + + describe('nested output', () => { + test('nested output is correct', async () => { + const cwd = new URL(`./nested/`, import.meta.url); + const tokens = JSON.parse(fs.readFileSync(new URL('tokens.json', cwd))); + await build(tokens, { + outDir: cwd, + plugins: [ + pluginJS({ + js: 'actual.js', + json: 'actual.json', + deep: true, + }), + ], + color: {}, + }); + expect(fs.readFileSync(new URL('actual.js', cwd), 'utf8'), `nested: JS`).toBe(fs.readFileSync(new URL('want.js', cwd), 'utf8')); + expect(fs.readFileSync(new URL('actual.d.ts', cwd), 'utf8'), `nested: TS`).toBe(fs.readFileSync(new URL('want.d.ts', cwd), 'utf8')); + expect(fs.readFileSync(new URL('actual.json', cwd), 'utf8'), `nested: JSON`).toBe(fs.readFileSync(new URL('want.json', cwd), 'utf8')); + }); + }); }); diff --git a/packages/plugin-js/test/nested/tokens.json b/packages/plugin-js/test/nested/tokens.json new file mode 100644 index 00000000..673d31e0 --- /dev/null +++ b/packages/plugin-js/test/nested/tokens.json @@ -0,0 +1,46 @@ +{ + "color": { + "$type": "color", + "$description": "Brand blue", + "black": {"$value": "#00193f"}, + "blue": { + "00": {"$value": "{color.black}"}, + "10": {"$value": "#062053"}, + "20": {"$value": "#0f2868"}, + "30": {"$value": "#192f7d"}, + "40": {"$value": "#223793"}, + "50": { + "$description": "Medium blue", + "$value": "#2b3faa" + }, + "60": {"$value": "#3764ba"}, + "70": {"$value": "#4887c9"}, + "80": {"$value": "#5ca9d7"}, + "90": {"$value": "#72cce5"}, + "100": {"$value": "#89eff1"} + }, + "white": {"$value": "#ffffff"} + }, + "ui": { + "fg": { + "$type": "color", + "$value": "{color.black}", + "$extensions": { + "mode": { + "light": "{color.black}", + "dark": "{color.white}" + } + } + }, + "bg": { + "$type": "color", + "$value": "{color.white}", + "$extensions": { + "mode": { + "light": "{color.white}", + "dark": "{color.black}" + } + } + } + } +} diff --git a/packages/plugin-js/test/nested/want.d.ts b/packages/plugin-js/test/nested/want.d.ts new file mode 100644 index 00000000..7f9c6d8e --- /dev/null +++ b/packages/plugin-js/test/nested/want.d.ts @@ -0,0 +1,60 @@ +/** + * Design Tokens + * Autogenerated from tokens.json. + * DO NOT EDIT! + */ + +import { + ColorToken, + ParsedColorToken, +} from '@cobalt-ui/core'; + +export declare const tokens: { + 'color.black': ColorToken['$value']; + 'color.blue.10': ColorToken['$value']; + 'color.blue.20': ColorToken['$value']; + 'color.blue.30': ColorToken['$value']; + 'color.blue.40': ColorToken['$value']; + 'color.blue.50': ColorToken['$value']; + 'color.blue.60': ColorToken['$value']; + 'color.blue.70': ColorToken['$value']; + 'color.blue.80': ColorToken['$value']; + 'color.blue.90': ColorToken['$value']; + 'color.blue.100': ColorToken['$value']; + 'color.blue.00': ColorToken['$value']; + 'color.white': ColorToken['$value']; + 'ui.fg': ColorToken['$value']; + 'ui.bg': ColorToken['$value']; +}; + +export declare const meta: { + 'color.black': ParsedColorToken; + 'color.blue.10': ParsedColorToken; + 'color.blue.20': ParsedColorToken; + 'color.blue.30': ParsedColorToken; + 'color.blue.40': ParsedColorToken; + 'color.blue.50': ParsedColorToken; + 'color.blue.60': ParsedColorToken; + 'color.blue.70': ParsedColorToken; + 'color.blue.80': ParsedColorToken; + 'color.blue.90': ParsedColorToken; + 'color.blue.100': ParsedColorToken; + 'color.blue.00': ParsedColorToken; + 'color.white': ParsedColorToken; + 'ui.fg': ParsedColorToken & { $extensions: { mode: typeof modes['ui.fg'] } }; + 'ui.bg': ParsedColorToken & { $extensions: { mode: typeof modes['ui.bg'] } }; +}; + +export declare const modes: { + 'ui.fg': { + light: ColorToken['$value']; + dark: ColorToken['$value']; + }; + 'ui.bg': { + light: ColorToken['$value']; + dark: ColorToken['$value']; + }; +}; + +export declare function token(tokenID: K, modeName?: never): typeof tokens[K]; +export declare function token(tokenID: K, modeName: M): typeof modes[K][M]; diff --git a/packages/plugin-js/test/nested/want.js b/packages/plugin-js/test/nested/want.js new file mode 100644 index 00000000..fb7cc21f --- /dev/null +++ b/packages/plugin-js/test/nested/want.js @@ -0,0 +1,314 @@ +/** + * Design Tokens + * Autogenerated from tokens.json. + * DO NOT EDIT! + */ + +export const tokens = { + color: { + black: '#00193f', + blue: { + 10: '#062053', + 20: '#0f2868', + 30: '#192f7d', + 40: '#223793', + /** Medium blue */ + 50: '#2b3faa', + 60: '#3764ba', + 70: '#4887c9', + 80: '#5ca9d7', + 90: '#72cce5', + 100: '#89eff1', + '00': '#00193f', + }, + white: '#ffffff', + }, + ui: { + fg: '#00193f', + bg: '#ffffff', + }, +}; + +export const meta = { + 'color.black': { + '_original': { + '$value': '#00193f', + }, + '_group': { + id: 'color', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.black', + '$type': 'color', + '$value': '#00193f', + }, + 'color.blue.10': { + '_original': { + '$value': '#062053', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.10', + '$type': 'color', + '$value': '#062053', + }, + 'color.blue.20': { + '_original': { + '$value': '#0f2868', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.20', + '$type': 'color', + '$value': '#0f2868', + }, + 'color.blue.30': { + '_original': { + '$value': '#192f7d', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.30', + '$type': 'color', + '$value': '#192f7d', + }, + 'color.blue.40': { + '_original': { + '$value': '#223793', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.40', + '$type': 'color', + '$value': '#223793', + }, + 'color.blue.50': { + '_original': { + '$description': 'Medium blue', + '$value': '#2b3faa', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.50', + '$type': 'color', + '$description': 'Medium blue', + '$value': '#2b3faa', + }, + 'color.blue.60': { + '_original': { + '$value': '#3764ba', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.60', + '$type': 'color', + '$value': '#3764ba', + }, + 'color.blue.70': { + '_original': { + '$value': '#4887c9', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.70', + '$type': 'color', + '$value': '#4887c9', + }, + 'color.blue.80': { + '_original': { + '$value': '#5ca9d7', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.80', + '$type': 'color', + '$value': '#5ca9d7', + }, + 'color.blue.90': { + '_original': { + '$value': '#72cce5', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.90', + '$type': 'color', + '$value': '#72cce5', + }, + 'color.blue.100': { + '_original': { + '$value': '#89eff1', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.100', + '$type': 'color', + '$value': '#89eff1', + }, + 'color.blue.00': { + '_original': { + '$value': '{color.black}', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.00', + '$type': 'color', + '$value': '#00193f', + }, + 'color.white': { + '_original': { + '$value': '#ffffff', + }, + '_group': { + id: 'color', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.white', + '$type': 'color', + '$value': '#ffffff', + }, + 'ui.fg': { + '_original': { + '$type': 'color', + '$value': '{color.black}', + '$extensions': { + mode: { + light: '{color.black}', + dark: '{color.white}', + }, + }, + }, + '_group': { + id: 'ui', + '$extensions': { + requiredModes: [], + }, + }, + id: 'ui.fg', + '$type': 'color', + '$value': '#00193f', + '$extensions': { + mode: { + light: '#00193f', + dark: '#ffffff', + }, + }, + }, + 'ui.bg': { + '_original': { + '$type': 'color', + '$value': '{color.white}', + '$extensions': { + mode: { + light: '{color.white}', + dark: '{color.black}', + }, + }, + }, + '_group': { + id: 'ui', + '$extensions': { + requiredModes: [], + }, + }, + id: 'ui.bg', + '$type': 'color', + '$value': '#ffffff', + '$extensions': { + mode: { + light: '#ffffff', + dark: '#00193f', + }, + }, + }, +}; + +export const modes = { + 'ui.fg': { + light: '#00193f', + dark: '#ffffff', + }, + 'ui.bg': { + light: '#ffffff', + dark: '#00193f', + }, +}; + +/** Get individual token */ +export function token(tokenID, modeName) { + if (modeName && modes[tokenID] && modeName in modes[tokenID]) return modes[tokenID][modeName]; + return tokens[tokenID]; +} diff --git a/packages/plugin-js/test/nested/want.json b/packages/plugin-js/test/nested/want.json new file mode 100644 index 00000000..02946480 --- /dev/null +++ b/packages/plugin-js/test/nested/want.json @@ -0,0 +1,301 @@ +{ + "tokens": { + "color": { + "black": "#00193f", + "blue": { + "10": "#062053", + "20": "#0f2868", + "30": "#192f7d", + "40": "#223793", + "50": "#2b3faa", + "60": "#3764ba", + "70": "#4887c9", + "80": "#5ca9d7", + "90": "#72cce5", + "100": "#89eff1", + "00": "#00193f" + }, + "white": "#ffffff" + }, + "ui": { + "fg": "#00193f", + "bg": "#ffffff" + } + }, + "meta": { + "color.black": { + "_original": { + "$value": "#00193f" + }, + "_group": { + "id": "color", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.black", + "$type": "color", + "$value": "#00193f" + }, + "color.blue.10": { + "_original": { + "$value": "#062053" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.10", + "$type": "color", + "$value": "#062053" + }, + "color.blue.20": { + "_original": { + "$value": "#0f2868" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.20", + "$type": "color", + "$value": "#0f2868" + }, + "color.blue.30": { + "_original": { + "$value": "#192f7d" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.30", + "$type": "color", + "$value": "#192f7d" + }, + "color.blue.40": { + "_original": { + "$value": "#223793" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.40", + "$type": "color", + "$value": "#223793" + }, + "color.blue.50": { + "_original": { + "$description": "Medium blue", + "$value": "#2b3faa" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.50", + "$type": "color", + "$description": "Medium blue", + "$value": "#2b3faa" + }, + "color.blue.60": { + "_original": { + "$value": "#3764ba" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.60", + "$type": "color", + "$value": "#3764ba" + }, + "color.blue.70": { + "_original": { + "$value": "#4887c9" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.70", + "$type": "color", + "$value": "#4887c9" + }, + "color.blue.80": { + "_original": { + "$value": "#5ca9d7" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.80", + "$type": "color", + "$value": "#5ca9d7" + }, + "color.blue.90": { + "_original": { + "$value": "#72cce5" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.90", + "$type": "color", + "$value": "#72cce5" + }, + "color.blue.100": { + "_original": { + "$value": "#89eff1" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.100", + "$type": "color", + "$value": "#89eff1" + }, + "color.blue.00": { + "_original": { + "$value": "{color.black}" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.00", + "$type": "color", + "$value": "#00193f" + }, + "color.white": { + "_original": { + "$value": "#ffffff" + }, + "_group": { + "id": "color", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.white", + "$type": "color", + "$value": "#ffffff" + }, + "ui.fg": { + "_original": { + "$type": "color", + "$value": "{color.black}", + "$extensions": { + "mode": { + "light": "{color.black}", + "dark": "{color.white}" + } + } + }, + "_group": { + "id": "ui", + "$extensions": { + "requiredModes": [] + } + }, + "id": "ui.fg", + "$type": "color", + "$value": "#00193f", + "$extensions": { + "mode": { + "light": "#00193f", + "dark": "#ffffff" + } + } + }, + "ui.bg": { + "_original": { + "$type": "color", + "$value": "{color.white}", + "$extensions": { + "mode": { + "light": "{color.white}", + "dark": "{color.black}" + } + } + }, + "_group": { + "id": "ui", + "$extensions": { + "requiredModes": [] + } + }, + "id": "ui.bg", + "$type": "color", + "$value": "#ffffff", + "$extensions": { + "mode": { + "light": "#ffffff", + "dark": "#00193f" + } + } + } + }, + "modes": { + "ui.fg": { + "light": "#00193f", + "dark": "#ffffff" + }, + "ui.bg": { + "light": "#ffffff", + "dark": "#00193f" + } + } +} diff --git a/packages/utils/src/object.ts b/packages/utils/src/object.ts index d670625e..6d59027d 100644 --- a/packages/utils/src/object.ts +++ b/packages/utils/src/object.ts @@ -14,3 +14,25 @@ export function cloneDeep(item: T): T { } return newObj as T; } + +/** set a nested value within an object safely + * We can assume that all token ids will be dot-notation, so we don't need to handle + * array accessors or string accessors. + */ +export function set(obj: Record, key: string, value: any): Record { + let [root, ...rest] = key.split('.'); + + if (root === '') { + return obj; + } + + if (rest.length === 0) { + obj[root!] = value; + + return obj; + } + + obj[root!] = obj[root!] ?? {}; + + return set(obj[root!], rest.join('.'), value); +} From 28fbf2df896d75f4edc49e336c81957be9ba52a8 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Fri, 18 Aug 2023 10:02:58 +0200 Subject: [PATCH 2/4] wip: fix js output --- packages/plugin-js/src/index.ts | 23 +- packages/plugin-js/test/nested/want.js | 482 +++++++++++----------- packages/plugin-js/test/nested/want.json | 488 ++++++++++++----------- 3 files changed, 509 insertions(+), 484 deletions(-) diff --git a/packages/plugin-js/src/index.ts b/packages/plugin-js/src/index.ts index 3a7dfd7f..0896d33b 100644 --- a/packages/plugin-js/src/index.ts +++ b/packages/plugin-js/src/index.ts @@ -134,21 +134,30 @@ export default function pluginJS(options?: Options): Plugin { ts.tokens.push(indent(`${objKey(token.id)}: ${t}['$value'];`, 1)); tsImports.add(t); } - js.meta![token.id] = { - _original: cloneDeep(token._original), - ...((token._group && {_group: token._group}) || {}), - ...cloneDeep(token as any), - }; + setToken( + js.meta!, + token.id, + { + _original: cloneDeep(token._original), + ...((token._group && {_group: token._group}) || {}), + ...cloneDeep(token as any), + }, + options?.deep, + ); if (buildTS) { const t = `Parsed${tokenTypes[token.$type]}`; ts.meta!.push(indent(`${objKey(token.id)}: ${t}${token.$extensions?.mode ? ` & { $extensions: { mode: typeof modes['${token.id}'] } }` : ''};`, 1)); tsImports.add(t); } if (token.$extensions?.mode) { - js.modes[token.id] = {}; + setToken(js.modes, token.id, {}, options?.deep); if (buildTS) ts.modes.push(indent(`${objKey(token.id)}: {`, 1)); for (const modeName of Object.keys(token.$extensions.mode)) { - js.modes[token.id]![modeName] = await transform(token, modeName); + if (options?.deep) { + setToken(js.modes, `${token.id}.${modeName}`, await transform(token, modeName), true); + } else { + js.modes[token.id]![modeName] = await transform(token, modeName); + } if (buildTS) ts.modes.push(indent(`${objKey(modeName)}: ${tokenTypes[token.$type]}['$value'];`, 2)); } if (buildTS) ts.modes.push(indent('};', 1)); diff --git a/packages/plugin-js/test/nested/want.js b/packages/plugin-js/test/nested/want.js index fb7cc21f..5e7708e2 100644 --- a/packages/plugin-js/test/nested/want.js +++ b/packages/plugin-js/test/nested/want.js @@ -30,280 +30,288 @@ export const tokens = { }; export const meta = { - 'color.black': { - '_original': { - '$value': '#00193f', - }, - '_group': { - id: 'color', - '$extensions': { - requiredModes: [], + color: { + black: { + '_original': { + '$value': '#00193f', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.black', - '$type': 'color', - '$value': '#00193f', - }, - 'color.blue.10': { - '_original': { - '$value': '#062053', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + '_group': { + id: 'color', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', }, + id: 'color.black', '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.10', - '$type': 'color', - '$value': '#062053', - }, - 'color.blue.20': { - '_original': { - '$value': '#0f2868', + '$value': '#00193f', }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + blue: { + 10: { + '_original': { + '$value': '#062053', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.10', + '$type': 'color', + '$value': '#062053', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.20', - '$type': 'color', - '$value': '#0f2868', - }, - 'color.blue.30': { - '_original': { - '$value': '#192f7d', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 20: { + '_original': { + '$value': '#0f2868', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.20', + '$type': 'color', + '$value': '#0f2868', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.30', - '$type': 'color', - '$value': '#192f7d', - }, - 'color.blue.40': { - '_original': { - '$value': '#223793', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 30: { + '_original': { + '$value': '#192f7d', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.30', + '$type': 'color', + '$value': '#192f7d', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.40', - '$type': 'color', - '$value': '#223793', - }, - 'color.blue.50': { - '_original': { - '$description': 'Medium blue', - '$value': '#2b3faa', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 40: { + '_original': { + '$value': '#223793', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.40', + '$type': 'color', + '$value': '#223793', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.50', - '$type': 'color', - '$description': 'Medium blue', - '$value': '#2b3faa', - }, - 'color.blue.60': { - '_original': { - '$value': '#3764ba', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 50: { + '_original': { + '$description': 'Medium blue', + '$value': '#2b3faa', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.50', + '$type': 'color', + '$description': 'Medium blue', + '$value': '#2b3faa', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.60', - '$type': 'color', - '$value': '#3764ba', - }, - 'color.blue.70': { - '_original': { - '$value': '#4887c9', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 60: { + '_original': { + '$value': '#3764ba', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.60', + '$type': 'color', + '$value': '#3764ba', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.70', - '$type': 'color', - '$value': '#4887c9', - }, - 'color.blue.80': { - '_original': { - '$value': '#5ca9d7', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 70: { + '_original': { + '$value': '#4887c9', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.70', + '$type': 'color', + '$value': '#4887c9', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.80', - '$type': 'color', - '$value': '#5ca9d7', - }, - 'color.blue.90': { - '_original': { - '$value': '#72cce5', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 80: { + '_original': { + '$value': '#5ca9d7', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.80', + '$type': 'color', + '$value': '#5ca9d7', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.90', - '$type': 'color', - '$value': '#72cce5', - }, - 'color.blue.100': { - '_original': { - '$value': '#89eff1', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 90: { + '_original': { + '$value': '#72cce5', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.90', + '$type': 'color', + '$value': '#72cce5', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.100', - '$type': 'color', - '$value': '#89eff1', - }, - 'color.blue.00': { - '_original': { - '$value': '{color.black}', - }, - '_group': { - id: 'color.blue', - '$extensions': { - requiredModes: [], + 100: { + '_original': { + '$value': '#89eff1', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.100', + '$type': 'color', + '$value': '#89eff1', + }, + '00': { + '_original': { + '$value': '{color.black}', + }, + '_group': { + id: 'color.blue', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.blue.00', + '$type': 'color', + '$value': '#00193f', }, - '$type': 'color', - '$description': 'Brand blue', - }, - id: 'color.blue.00', - '$type': 'color', - '$value': '#00193f', - }, - 'color.white': { - '_original': { - '$value': '#ffffff', }, - '_group': { - id: 'color', - '$extensions': { - requiredModes: [], + white: { + '_original': { + '$value': '#ffffff', }, + '_group': { + id: 'color', + '$extensions': { + requiredModes: [], + }, + '$type': 'color', + '$description': 'Brand blue', + }, + id: 'color.white', '$type': 'color', - '$description': 'Brand blue', + '$value': '#ffffff', }, - id: 'color.white', - '$type': 'color', - '$value': '#ffffff', }, - 'ui.fg': { - '_original': { + ui: { + fg: { + '_original': { + '$type': 'color', + '$value': '{color.black}', + '$extensions': { + mode: { + light: '{color.black}', + dark: '{color.white}', + }, + }, + }, + '_group': { + id: 'ui', + '$extensions': { + requiredModes: [], + }, + }, + id: 'ui.fg', '$type': 'color', - '$value': '{color.black}', + '$value': '#00193f', '$extensions': { mode: { - light: '{color.black}', - dark: '{color.white}', + light: '#00193f', + dark: '#ffffff', }, }, }, - '_group': { - id: 'ui', - '$extensions': { - requiredModes: [], + bg: { + '_original': { + '$type': 'color', + '$value': '{color.white}', + '$extensions': { + mode: { + light: '{color.white}', + dark: '{color.black}', + }, + }, }, - }, - id: 'ui.fg', - '$type': 'color', - '$value': '#00193f', - '$extensions': { - mode: { - light: '#00193f', - dark: '#ffffff', + '_group': { + id: 'ui', + '$extensions': { + requiredModes: [], + }, }, - }, - }, - 'ui.bg': { - '_original': { + id: 'ui.bg', '$type': 'color', - '$value': '{color.white}', + '$value': '#ffffff', '$extensions': { mode: { - light: '{color.white}', - dark: '{color.black}', + light: '#ffffff', + dark: '#00193f', }, }, }, - '_group': { - id: 'ui', - '$extensions': { - requiredModes: [], - }, - }, - id: 'ui.bg', - '$type': 'color', - '$value': '#ffffff', - '$extensions': { - mode: { - light: '#ffffff', - dark: '#00193f', - }, - }, }, }; export const modes = { - 'ui.fg': { - light: '#00193f', - dark: '#ffffff', - }, - 'ui.bg': { - light: '#ffffff', - dark: '#00193f', + ui: { + fg: { + light: '#00193f', + dark: '#ffffff', + }, + bg: { + light: '#ffffff', + dark: '#00193f', + }, }, }; diff --git a/packages/plugin-js/test/nested/want.json b/packages/plugin-js/test/nested/want.json index 02946480..a982ad36 100644 --- a/packages/plugin-js/test/nested/want.json +++ b/packages/plugin-js/test/nested/want.json @@ -23,279 +23,287 @@ } }, "meta": { - "color.black": { - "_original": { - "$value": "#00193f" - }, - "_group": { - "id": "color", - "$extensions": { - "requiredModes": [] + "color": { + "black": { + "_original": { + "$value": "#00193f" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.black", - "$type": "color", - "$value": "#00193f" - }, - "color.blue.10": { - "_original": { - "$value": "#062053" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "_group": { + "id": "color", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" }, + "id": "color.black", "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.10", - "$type": "color", - "$value": "#062053" - }, - "color.blue.20": { - "_original": { - "$value": "#0f2868" + "$value": "#00193f" }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "blue": { + "10": { + "_original": { + "$value": "#062053" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.10", + "$type": "color", + "$value": "#062053" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.20", - "$type": "color", - "$value": "#0f2868" - }, - "color.blue.30": { - "_original": { - "$value": "#192f7d" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "20": { + "_original": { + "$value": "#0f2868" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.20", + "$type": "color", + "$value": "#0f2868" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.30", - "$type": "color", - "$value": "#192f7d" - }, - "color.blue.40": { - "_original": { - "$value": "#223793" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "30": { + "_original": { + "$value": "#192f7d" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.30", + "$type": "color", + "$value": "#192f7d" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.40", - "$type": "color", - "$value": "#223793" - }, - "color.blue.50": { - "_original": { - "$description": "Medium blue", - "$value": "#2b3faa" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "40": { + "_original": { + "$value": "#223793" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.40", + "$type": "color", + "$value": "#223793" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.50", - "$type": "color", - "$description": "Medium blue", - "$value": "#2b3faa" - }, - "color.blue.60": { - "_original": { - "$value": "#3764ba" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "50": { + "_original": { + "$description": "Medium blue", + "$value": "#2b3faa" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.50", + "$type": "color", + "$description": "Medium blue", + "$value": "#2b3faa" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.60", - "$type": "color", - "$value": "#3764ba" - }, - "color.blue.70": { - "_original": { - "$value": "#4887c9" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "60": { + "_original": { + "$value": "#3764ba" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.60", + "$type": "color", + "$value": "#3764ba" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.70", - "$type": "color", - "$value": "#4887c9" - }, - "color.blue.80": { - "_original": { - "$value": "#5ca9d7" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "70": { + "_original": { + "$value": "#4887c9" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.70", + "$type": "color", + "$value": "#4887c9" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.80", - "$type": "color", - "$value": "#5ca9d7" - }, - "color.blue.90": { - "_original": { - "$value": "#72cce5" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "80": { + "_original": { + "$value": "#5ca9d7" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.80", + "$type": "color", + "$value": "#5ca9d7" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.90", - "$type": "color", - "$value": "#72cce5" - }, - "color.blue.100": { - "_original": { - "$value": "#89eff1" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "90": { + "_original": { + "$value": "#72cce5" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.90", + "$type": "color", + "$value": "#72cce5" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.100", - "$type": "color", - "$value": "#89eff1" - }, - "color.blue.00": { - "_original": { - "$value": "{color.black}" - }, - "_group": { - "id": "color.blue", - "$extensions": { - "requiredModes": [] + "100": { + "_original": { + "$value": "#89eff1" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.100", + "$type": "color", + "$value": "#89eff1" }, - "$type": "color", - "$description": "Brand blue" - }, - "id": "color.blue.00", - "$type": "color", - "$value": "#00193f" - }, - "color.white": { - "_original": { - "$value": "#ffffff" + "00": { + "_original": { + "$value": "{color.black}" + }, + "_group": { + "id": "color.blue", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.blue.00", + "$type": "color", + "$value": "#00193f" + } }, - "_group": { - "id": "color", - "$extensions": { - "requiredModes": [] + "white": { + "_original": { + "$value": "#ffffff" }, + "_group": { + "id": "color", + "$extensions": { + "requiredModes": [] + }, + "$type": "color", + "$description": "Brand blue" + }, + "id": "color.white", "$type": "color", - "$description": "Brand blue" - }, - "id": "color.white", - "$type": "color", - "$value": "#ffffff" + "$value": "#ffffff" + } }, - "ui.fg": { - "_original": { + "ui": { + "fg": { + "_original": { + "$type": "color", + "$value": "{color.black}", + "$extensions": { + "mode": { + "light": "{color.black}", + "dark": "{color.white}" + } + } + }, + "_group": { + "id": "ui", + "$extensions": { + "requiredModes": [] + } + }, + "id": "ui.fg", "$type": "color", - "$value": "{color.black}", + "$value": "#00193f", "$extensions": { "mode": { - "light": "{color.black}", - "dark": "{color.white}" + "light": "#00193f", + "dark": "#ffffff" } } }, - "_group": { - "id": "ui", - "$extensions": { - "requiredModes": [] - } - }, - "id": "ui.fg", - "$type": "color", - "$value": "#00193f", - "$extensions": { - "mode": { - "light": "#00193f", - "dark": "#ffffff" - } - } - }, - "ui.bg": { - "_original": { + "bg": { + "_original": { + "$type": "color", + "$value": "{color.white}", + "$extensions": { + "mode": { + "light": "{color.white}", + "dark": "{color.black}" + } + } + }, + "_group": { + "id": "ui", + "$extensions": { + "requiredModes": [] + } + }, + "id": "ui.bg", "$type": "color", - "$value": "{color.white}", + "$value": "#ffffff", "$extensions": { "mode": { - "light": "{color.white}", - "dark": "{color.black}" + "light": "#ffffff", + "dark": "#00193f" } } - }, - "_group": { - "id": "ui", - "$extensions": { - "requiredModes": [] - } - }, - "id": "ui.bg", - "$type": "color", - "$value": "#ffffff", - "$extensions": { - "mode": { - "light": "#ffffff", - "dark": "#00193f" - } } } }, "modes": { - "ui.fg": { - "light": "#00193f", - "dark": "#ffffff" - }, - "ui.bg": { - "light": "#ffffff", - "dark": "#00193f" + "ui": { + "fg": { + "light": "#00193f", + "dark": "#ffffff" + }, + "bg": { + "light": "#ffffff", + "dark": "#00193f" + } } } } From ed2eaff1d8665d6a99bbfe879cf75ba4fa11132b Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Fri, 18 Aug 2023 10:54:56 +0200 Subject: [PATCH 3/4] feat: optionally nest TS output as well --- packages/plugin-js/src/index.ts | 55 ++++++++++----- packages/plugin-js/test/nested/want.d.ts | 88 ++++++++++++++---------- 2 files changed, 89 insertions(+), 54 deletions(-) diff --git a/packages/plugin-js/src/index.ts b/packages/plugin-js/src/index.ts index 0896d33b..50318455 100644 --- a/packages/plugin-js/src/index.ts +++ b/packages/plugin-js/src/index.ts @@ -21,15 +21,15 @@ export interface Options { } interface JSResult { - tokens: {[id: string]: ParsedToken['$value']}; - meta?: {[id: string]: Token}; - modes: {[id: string]: Mode}; + tokens: {[id: string]: ParsedToken['$value'] | JSResult['tokens']}; + meta?: {[id: string]: Token | JSResult['meta']}; + modes: {[id: string]: Mode}; } interface TSResult { - tokens: string[]; - meta?: string[]; - modes: string[]; + tokens: {[id: string]: string | TSResult['tokens']}; + meta?: {[id: string]: string | TSResult['meta']}; + modes: {[id: string]: string | TSResult['modes']}; } const tokenTypes: Record = { @@ -78,6 +78,23 @@ ${indent(`}${indentLv === 0 ? ';' : ''}`, indentLv)}`; throw new Error(`Could not serialize ${value}`); } +/** serialize TS ref into string */ +export function serializeTS(value: unknown, options?: {indentLv?: number}): string { + const indentLv = options?.indentLv || 0; + if (typeof value === 'number' || typeof value === 'string') return `${value}`; + if (value === undefined) return 'undefined'; + if (value === null) return 'null'; + if (Array.isArray(value)) return `[${value.map((item) => serializeTS(item, {indentLv: indentLv + 1})).join(', ')}]`; + if (typeof value === 'function') throw new Error(`Cannot serialize function ${value}`); + if (typeof value === 'object') + return `{ +${Object.entries(value) + .map(([k, v]) => `${indent(objKey(k), indentLv + 1)}: ${serializeTS(v, {indentLv: indentLv + 1})}`) + .join(';\n')}; +${indent(`}${indentLv === 0 ? ';' : ''}`, indentLv)}`; + throw new Error(`Could not serialize ${value}`); +} + function defaultTransform(token: ParsedToken, mode?: string): (typeof token)['$value'] { if (!mode || !token.$extensions?.mode || !(mode in token.$extensions.mode) || !token.$extensions.mode[mode]) return token.$value; const modeVal = token.$extensions.mode[mode]; @@ -125,13 +142,13 @@ export default function pluginJS(options?: Options): Plugin { meta: {}, modes: {}, }; - const ts: TSResult = {tokens: [], meta: [], modes: []}; + const ts: TSResult = {tokens: {}, meta: {}, modes: {}}; const transform = (typeof options?.transform === 'function' && options.transform) || defaultTransform; for (const token of tokens) { setToken(js.tokens, token.id, await transform(token), options?.deep); if (buildTS) { const t = tokenTypes[token.$type]; - ts.tokens.push(indent(`${objKey(token.id)}: ${t}['$value'];`, 1)); + setToken(ts.tokens, token.id, `${t}['$value']`, options?.deep); tsImports.add(t); } setToken( @@ -146,21 +163,27 @@ export default function pluginJS(options?: Options): Plugin { ); if (buildTS) { const t = `Parsed${tokenTypes[token.$type]}`; - ts.meta!.push(indent(`${objKey(token.id)}: ${t}${token.$extensions?.mode ? ` & { $extensions: { mode: typeof modes['${token.id}'] } }` : ''};`, 1)); + const modeAccessor = options?.deep ? token.id.replace('.', "']['") : token.id; + setToken(ts.meta!, token.id, `${t}${token.$extensions?.mode ? ` & { $extensions: { mode: typeof modes['${modeAccessor}'] } }` : ''}`, options?.deep); tsImports.add(t); } if (token.$extensions?.mode) { setToken(js.modes, token.id, {}, options?.deep); - if (buildTS) ts.modes.push(indent(`${objKey(token.id)}: {`, 1)); + if (buildTS) setToken(ts.modes, token.id, {}, options?.deep); for (const modeName of Object.keys(token.$extensions.mode)) { if (options?.deep) { setToken(js.modes, `${token.id}.${modeName}`, await transform(token, modeName), true); } else { js.modes[token.id]![modeName] = await transform(token, modeName); } - if (buildTS) ts.modes.push(indent(`${objKey(modeName)}: ${tokenTypes[token.$type]}['$value'];`, 2)); + if (buildTS) { + if (options?.deep) { + setToken(ts.modes, `${token.id}.${modeName}`, `${tokenTypes[token.$type]}['$value']`, true); + } else { + (ts.modes[token.id] as TSResult['modes'])[modeName] = `${tokenTypes[token.$type]}['$value']`; + } + } } - if (buildTS) ts.modes.push(indent('};', 1)); } } @@ -220,12 +243,10 @@ export function token(tokenID, modeName) { ...sortedTypeImports.map((m) => indent(`${m},`, 1)), `} from '@cobalt-ui/core';`, '', - 'export declare const tokens: {', - ...ts.tokens, - '};', + `export declare const tokens: ${serializeTS(ts.tokens)}`, '', - ...(ts.meta ? ['export declare const meta: {', ...ts.meta, '};', ''] : []), - `export declare const modes: ${ts.modes.length ? `{\n${ts.modes.join('\n')}\n}` : 'Record'};`, + ...(ts.meta ? [`export declare const meta: ${serializeTS(ts.meta)}`, ''] : []), + `export declare const modes: ${Object.keys(ts.modes).length ? serializeTS(ts.modes) : 'Record;'}`, '', `export declare function token(tokenID: K, modeName?: never): typeof tokens[K];`, `export declare function token(tokenID: K, modeName: M): typeof modes[K][M];`, diff --git a/packages/plugin-js/test/nested/want.d.ts b/packages/plugin-js/test/nested/want.d.ts index 7f9c6d8e..824e2b4c 100644 --- a/packages/plugin-js/test/nested/want.d.ts +++ b/packages/plugin-js/test/nested/want.d.ts @@ -10,49 +10,63 @@ import { } from '@cobalt-ui/core'; export declare const tokens: { - 'color.black': ColorToken['$value']; - 'color.blue.10': ColorToken['$value']; - 'color.blue.20': ColorToken['$value']; - 'color.blue.30': ColorToken['$value']; - 'color.blue.40': ColorToken['$value']; - 'color.blue.50': ColorToken['$value']; - 'color.blue.60': ColorToken['$value']; - 'color.blue.70': ColorToken['$value']; - 'color.blue.80': ColorToken['$value']; - 'color.blue.90': ColorToken['$value']; - 'color.blue.100': ColorToken['$value']; - 'color.blue.00': ColorToken['$value']; - 'color.white': ColorToken['$value']; - 'ui.fg': ColorToken['$value']; - 'ui.bg': ColorToken['$value']; + color: { + black: ColorToken['$value']; + blue: { + 10: ColorToken['$value']; + 20: ColorToken['$value']; + 30: ColorToken['$value']; + 40: ColorToken['$value']; + 50: ColorToken['$value']; + 60: ColorToken['$value']; + 70: ColorToken['$value']; + 80: ColorToken['$value']; + 90: ColorToken['$value']; + 100: ColorToken['$value']; + '00': ColorToken['$value']; + }; + white: ColorToken['$value']; + }; + ui: { + fg: ColorToken['$value']; + bg: ColorToken['$value']; + }; }; export declare const meta: { - 'color.black': ParsedColorToken; - 'color.blue.10': ParsedColorToken; - 'color.blue.20': ParsedColorToken; - 'color.blue.30': ParsedColorToken; - 'color.blue.40': ParsedColorToken; - 'color.blue.50': ParsedColorToken; - 'color.blue.60': ParsedColorToken; - 'color.blue.70': ParsedColorToken; - 'color.blue.80': ParsedColorToken; - 'color.blue.90': ParsedColorToken; - 'color.blue.100': ParsedColorToken; - 'color.blue.00': ParsedColorToken; - 'color.white': ParsedColorToken; - 'ui.fg': ParsedColorToken & { $extensions: { mode: typeof modes['ui.fg'] } }; - 'ui.bg': ParsedColorToken & { $extensions: { mode: typeof modes['ui.bg'] } }; + color: { + black: ParsedColorToken; + blue: { + 10: ParsedColorToken; + 20: ParsedColorToken; + 30: ParsedColorToken; + 40: ParsedColorToken; + 50: ParsedColorToken; + 60: ParsedColorToken; + 70: ParsedColorToken; + 80: ParsedColorToken; + 90: ParsedColorToken; + 100: ParsedColorToken; + '00': ParsedColorToken; + }; + white: ParsedColorToken; + }; + ui: { + fg: ParsedColorToken & { $extensions: { mode: typeof modes['ui']['fg'] } }; + bg: ParsedColorToken & { $extensions: { mode: typeof modes['ui']['bg'] } }; + }; }; export declare const modes: { - 'ui.fg': { - light: ColorToken['$value']; - dark: ColorToken['$value']; - }; - 'ui.bg': { - light: ColorToken['$value']; - dark: ColorToken['$value']; + ui: { + fg: { + light: ColorToken['$value']; + dark: ColorToken['$value']; + }; + bg: { + light: ColorToken['$value']; + dark: ColorToken['$value']; + }; }; }; From 7885492ce5f4c4ace5f2c6bf6543f07d47d9fe70 Mon Sep 17 00:00:00 2001 From: Mike Engel Date: Fri, 18 Aug 2023 11:01:44 +0200 Subject: [PATCH 4/4] fix: add changeset --- .changeset/small-birds-pay.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/small-birds-pay.md diff --git a/.changeset/small-birds-pay.md b/.changeset/small-birds-pay.md new file mode 100644 index 00000000..62ba446b --- /dev/null +++ b/.changeset/small-birds-pay.md @@ -0,0 +1,6 @@ +--- +'@cobalt-ui/plugin-js': minor +'@cobalt-ui/utils': minor +--- + +Allow JS plugin output to be nested