diff --git a/.changeset/curvy-comics-heal.md b/.changeset/curvy-comics-heal.md new file mode 100644 index 0000000..d49da7e --- /dev/null +++ b/.changeset/curvy-comics-heal.md @@ -0,0 +1,5 @@ +--- +'@tokens-studio/sd-transforms': patch +--- + +Fix types for expandComposites functions, no longer trips up on key value pairs with primitive values during parsing process. diff --git a/package-lock.json b/package-lock.json index 2ddb384..814d09e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tokens-studio/sd-transforms", - "version": "0.11.7", + "version": "0.11.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tokens-studio/sd-transforms", - "version": "0.11.7", + "version": "0.11.9", "license": "MIT", "dependencies": { "@tokens-studio/types": "^0.2.4", diff --git a/src/parsers/expand-composites.ts b/src/parsers/expand-composites.ts index 754347b..65fd181 100644 --- a/src/parsers/expand-composites.ts +++ b/src/parsers/expand-composites.ts @@ -73,8 +73,8 @@ function shouldExpand( } function recurse( - slice: DeepKeyTokenMap, - copy: DeepKeyTokenMap, + slice: DeepKeyTokenMap | SingleToken, + copy: DeepKeyTokenMap | SingleToken, filePath: string, transformOpts: TransformOptions = {}, ) { @@ -91,6 +91,9 @@ function recurse( for (const key in slice) { const token = slice[key]; + if (typeof token !== 'object' || token === null) { + continue; + } const { type } = token; if (token.value && type) { if (typeof type === 'string' && expandablesAsStringsArr.includes(type)) { @@ -106,20 +109,17 @@ function recurse( slice[key] = expandToken(token, expandType === 'shadow'); } } - } else if (typeof token === 'object') { - // TODO: figure out why we have to hack this typecast, if a value doesn't have a value & type, - // it is definitely a nested DeepKeyTokenMap and not a SingleToken, but TS seems to think it must be - // a SingleToken after this if statement - recurse(token as unknown as DeepKeyTokenMap, copy, filePath, transformOpts); + } else { + recurse(token, copy, filePath, transformOpts); } } } export function expandComposites( - dictionary: DeepKeyTokenMap, + dictionary: DeepKeyTokenMap | SingleToken, filePath: string, transformOpts?: TransformOptions, -): DeepKeyTokenMap { +): DeepKeyTokenMap | SingleToken { const copy = { ...dictionary }; recurse(copy, copy, filePath, transformOpts); return copy; diff --git a/src/parsers/resolveReference.ts b/src/parsers/resolveReference.ts index b707912..8423b51 100644 --- a/src/parsers/resolveReference.ts +++ b/src/parsers/resolveReference.ts @@ -22,7 +22,7 @@ type boundGetRef = ( export function resolveReference['value']>( tokenValue: T, - copy: DeepKeyTokenMap, + copy: DeepKeyTokenMap | SingleToken, ): T { const boundGetRef = getReferences.bind({ properties: copy }) as boundGetRef; diff --git a/src/registerTransforms.ts b/src/registerTransforms.ts index d68c673..8539576 100644 --- a/src/registerTransforms.ts +++ b/src/registerTransforms.ts @@ -1,4 +1,4 @@ -import { Core } from 'style-dictionary'; +import { Core, DesignTokens } from 'style-dictionary'; import { transformDimension } from './transformDimension.js'; import { transformHEXRGBaForCSS } from './css/transformHEXRGBa.js'; import { transformShadowForCSS } from './css/transformShadow.js'; @@ -62,7 +62,7 @@ export async function registerTransforms(sd: Core, transformOpts?: TransformOpti const excluded = excludeParentKeys(obj, transformOpts); const withFontStyles = addFontStyles(excluded, transformOpts); const expanded = expandComposites(withFontStyles, filePath, transformOpts); - return expanded; + return expanded as DesignTokens; }, }); } diff --git a/test/spec/parsers/expand.spec.ts b/test/spec/parsers/expand.spec.ts index 66f36a3..83b5ea7 100644 --- a/test/spec/parsers/expand.spec.ts +++ b/test/spec/parsers/expand.spec.ts @@ -373,4 +373,18 @@ describe('expand', () => { }, }); }); + + it('should not trip up when the recursed token contains a primitive value', () => { + expect( + expandComposites( + { + value: '#ffffff', + type: 'color', + comment: null, + } as SingleToken, + 'foo/bar.json', + { expand: { typography: true } }, + ), + ); + }); });