import { SpecifyDesignTokenTypeName, TokenState } from '@specifyapp/specify-design-token-format'; import { matchJsonValue } from '../../utils/jsonValueMatcher.js'; import { renderColor } from './tokenTypes/color.js'; import { renderBorder } from './tokenTypes/border.js'; import { renderBreakpoint } from './tokenTypes/breakpoint.js'; import { renderCubicBezier } from './tokenTypes/cubicBezier.js'; import { renderDimension } from './tokenTypes/dimension.js'; import { renderDuration } from './tokenTypes/duration.js'; import { renderFont } from './tokenTypes/font.js'; import { renderFontWeight } from './tokenTypes/fontWeight.js'; import { renderGradient } from './tokenTypes/gradient.js'; import { renderGradients } from './tokenTypes/gradients.js'; import { renderOpacity } from './tokenTypes/opacity.js'; import { renderRadii } from './tokenTypes/radii.js'; import { renderRadius } from './tokenTypes/radius.js'; import { renderShadow } from './tokenTypes/shadow.js'; import { renderShadows } from './tokenTypes/shadows.js'; import { renderSpacing } from './tokenTypes/spacing.js'; import { renderSpacings } from './tokenTypes/spacings.js'; import { renderTextAlignHorizontal } from './tokenTypes/textAlignHorizontal.js'; import { renderTextDecoration } from './tokenTypes/textDecoration.js'; import { renderTextStyle } from './tokenTypes/textStyle.js'; import { renderTransition } from './tokenTypes/transition.js'; import { dataOfToken, makeRenderer } from './template.js'; export type ConvertedOutput = { [type in SpecifyDesignTokenTypeName]?: { [name: string]: string } }; export type ConversionOutput = { variableName: string; value: string; }; export type MultipleConversionOutput = Array< ConversionOutput & { type: SpecifyDesignTokenTypeName } >; export function convertTokens( tokens: Array, tokenNameTemplate: string, ): ConvertedOutput { const outputTokens = {} as ConvertedOutput; const renderVariable = makeRenderer(tokenNameTemplate); for (const token of tokens) { for (const mode of token.modes) { const variableName = renderVariable( dataOfToken(token, token.modes.length === 1 ? undefined : mode), ); const wrapValue = (value: string | undefined) => { if (!value) return; return { variableName, value }; }; const output = matchJsonValue( { border: v => renderBorder(v, variableName), breakpoint: v => wrapValue(renderBreakpoint(v)), color: v => wrapValue(renderColor(v)), cubicBezier: v => wrapValue(renderCubicBezier(v)), dimension: v => wrapValue(renderDimension(v)), duration: v => wrapValue(renderDuration(v)), font: v => wrapValue(renderFont(v)), fontWeight: v => wrapValue(renderFontWeight(v)), gradient: v => wrapValue(renderGradient(v)), gradients: v => renderGradients(v, variableName), opacity: v => wrapValue(renderOpacity(v)), radii: v => wrapValue(renderRadii(v)), radius: v => wrapValue(renderRadius(v)), shadow: v => wrapValue(renderShadow(v)), shadows: v => renderShadows(v, variableName), spacing: v => wrapValue(renderSpacing(v)), spacings: v => wrapValue(renderSpacings(v)), textAlignHorizontal: v => wrapValue(renderTextAlignHorizontal(v)), textDecoration: v => wrapValue(renderTextDecoration(v)), textStyle: v => renderTextStyle(v, variableName), transition: v => renderTransition(v, variableName), }, () => { return undefined; }, token, mode, ); if (!output) continue; if (Array.isArray(output)) { for (const converted of output) { outputTokens[converted.type] ??= {}; outputTokens[converted.type]![converted.variableName] = converted.value; } } else { outputTokens[token.type] ??= {}; outputTokens[token.type]![output.variableName] = output.value; } } } return outputTokens; }