import poise from '../../tokens/presets/poise.json'; import prestige from '../../tokens/presets/prestige.json'; import pulse from '../../tokens/presets/pulse.json'; import { MODES, PLATFORMS, PRESETS } from '../constants'; import type { Preset } from '../types'; import { cloneJson, isRecord } from '../utils/common'; import type { ConcreteTokenValue, PackageTokenExpression, PresetExpressionData, PresetTokenExpression, } from './contracts'; const rawPresets: Readonly> = { poise, prestige, pulse, }; function mergePreset(base: unknown, delta: unknown): unknown { if (!isRecord(base) || !isRecord(delta) || '$value' in delta) return cloneJson(delta); const result = cloneJson(base) as Record; for (const [key, value] of Object.entries(delta)) { result[key] = key in result ? mergePreset(result[key], value) : cloneJson(value); } return result; } function toExpression(value: ConcreteTokenValue): PackageTokenExpression { if (typeof value === 'string') { const reference = /^\{([^{}]+)\}$/.exec(value); if (reference) return { kind: 'reference', ref: reference[1] }; } return { kind: 'literal', value }; } function expressionKey(expression: PresetTokenExpression): string { return [expression.platform ?? '', expression.mode, expression.tokenPath].join(':'); } function collectPresetExpressions(preset: unknown): readonly PresetTokenExpression[] { const expressions: PresetTokenExpression[] = []; function walk(value: unknown, path: readonly string[], inheritedType?: string): void { if (!isRecord(value)) return; const type = typeof value.$type === 'string' ? value.$type : inheritedType; if ('$value' in value) { const tokenValue = value.$value; if (typeof tokenValue !== 'string' && typeof tokenValue !== 'number') return; let tokenPath: string; let mode: PresetTokenExpression['mode'] = 'invariant'; let platform: PresetTokenExpression['platform']; if (path[0] === 'modes' && MODES.includes(path[1] as (typeof MODES)[number])) { mode = path[1] as (typeof MODES)[number]; tokenPath = path.slice(2).join('.'); } else if ( path[0] === 'platform' && PLATFORMS.includes(path[1] as (typeof PLATFORMS)[number]) ) { platform = path[1] as (typeof PLATFORMS)[number]; tokenPath = path.slice(2).join('.'); } else { tokenPath = path.join('.'); } if (!tokenPath || !type) return; expressions.push({ tokenPath, type, mode, ...(platform ? { platform } : {}), expression: toExpression(tokenValue), }); return; } for (const [key, child] of Object.entries(value)) { if (key.startsWith('$')) continue; if (path.length === 0 && key === 'typography') continue; walk(child, [...path, key], type); } } walk(preset, []); return expressions.sort((left, right) => expressionKey(left).localeCompare(expressionKey(right))); } export function walkShippedPresetExpressions(): PresetExpressionData { const mergedPresets: Record = { poise: rawPresets.poise, prestige: mergePreset(rawPresets.poise, rawPresets.prestige), pulse: mergePreset(rawPresets.poise, rawPresets.pulse), }; return { source: 'shipped-preset-json', byPreset: Object.fromEntries( PRESETS.map((preset) => [preset, collectPresetExpressions(mergedPresets[preset])]), ) as unknown as PresetExpressionData['byPreset'], }; }