diff --git a/.changeset/cyan-pots-turn.md b/.changeset/cyan-pots-turn.md new file mode 100644 index 0000000..309998d --- /dev/null +++ b/.changeset/cyan-pots-turn.md @@ -0,0 +1,5 @@ +--- +'@runroom/design-tokens': patch +--- + +Add detection for duplicate tokens name diff --git a/src/functions/getTokens.ts b/src/functions/getTokens.ts index 1720631..0903a11 100644 --- a/src/functions/getTokens.ts +++ b/src/functions/getTokens.ts @@ -1,6 +1,7 @@ import { FigmaComponent, FigmaFrame } from '@/types/figma'; import { DesignTokensGenerator, + Token, TokenCollection, TokenPayload, Tokens, @@ -9,6 +10,7 @@ import { import { snakeCase } from './stringManipulation.ts'; import { DESIGN_TOKENS, DesignPages } from '@/designTokensPages.ts'; import { validateFrameName } from './ensureType.ts'; +import { logWarning } from '@/functions/logger.ts'; const treeParser = (frames: (FigmaFrame | FigmaComponent)[]): T[] => { const components: T[] = []; @@ -50,15 +52,48 @@ const buildPayload =

(payload: object, componentsKey: } as P; }; -const mergeTokens = (payload: any, token: any): any | undefined => { +const isKeyDuplicated = ( + payload: T, + token: K, + key: string +) => Object.keys(payload).filter(payloadKey => payloadKey === (token[key] as any).name).length; + +const renameDuplicatedToken = ( + payload: T, + token: K +) => { + let duplicatedToken = token; + Object.keys(payload).forEach(key => { + const payloadToken = payload[key] as any as Token; + + if (payloadToken.name === (duplicatedToken[key] as Token).name) { + const duplicatedKey = `${key}-duplicate`; + (duplicatedToken[key] as Token).name = `${(duplicatedToken[key] as Token).name}-duplicate`; + duplicatedToken = { [duplicatedKey]: duplicatedToken[key] } as K; + } + }); + + return duplicatedToken; +}; + +const mergeTokens = (payload: T, token: K): T => { const key = Object.keys(token)[0]; + if (!payload[key]) { Object.assign(payload, token); return payload; } - const newPayload = mergeTokens(payload[key], token[key]); + if (isKeyDuplicated(payload, token, key)) { + logWarning(`Duplicated token name: ${(token[key] as Token).name}`); + const duplicatedToken = renameDuplicatedToken(payload, token); + + Object.assign(payload, duplicatedToken); + return payload; + } + + const newPayload: T = mergeTokens(payload[key] as T, token[key] as K); return { ...payload, diff --git a/src/functions/logger.ts b/src/functions/logger.ts index 2ae7351..72dac24 100644 --- a/src/functions/logger.ts +++ b/src/functions/logger.ts @@ -10,8 +10,9 @@ const EMOJIS = { }; const log = (message: string, emoji = '') => { + const reset = '\x1b[0m'; // eslint-disable-next-line no-console - console.log(`\n${message} ${emoji}`); + console.info(`\n${reset}${emoji} ${message}\n`); }; const logError = (message: string) => {