import { ResolvableModeLevelAlias, ResolvableTopLevelAlias, ResolvableValueLevelAlias, TokenState, UnresolvableModeLevelAlias, UnresolvableValueLevelAlias, } from '@specifyapp/specify-design-token-format'; import handlebars from 'handlebars'; handlebars.registerHelper('join', function (array: Array, separator: string) { return array.join(separator); }); export const dataOfToken = (token: TokenState, mode: string | undefined): RawTokenData => { const groups = token.path.length <= 1 ? [] : token.path.toArray().slice(0, token.path.length - 1); const collectionState = token.getCollection(); const collection = collectionState?.name; let groupsBeforeCollection: Array | undefined = groups.length > 0 && collectionState ? groups.slice(0, collectionState.path.length - 1) : []; let groupsAfterCollection: Array | undefined = groups.length > 0 && collectionState ? groups.slice(collectionState.path.length) : []; return { groups, path: groups, groupList: groups, groupsBeforeCollection, groupsAfterCollection, collection, mode, token: token.name, }; }; export const dataOfResolvedStatefulAlias = ( resolved: ResolvableTopLevelAlias | ResolvableModeLevelAlias | ResolvableValueLevelAlias, mode?: string, ): RawTokenData => dataOfToken( resolved.tokenState, resolved instanceof ResolvableTopLevelAlias ? mode : resolved.targetMode, ); export function dataOfUnresolvedAlias( alias: UnresolvableModeLevelAlias | UnresolvableValueLevelAlias, ): RawTokenData { const token = alias.targetPath.at(alias.targetPath.length - 1)!; const path = alias.targetPath.length > 1 ? alias.targetPath.toArray().slice(0, alias.targetPath.length - 1) : []; return { path, groups: path, groupList: path, collection: undefined, groupsBeforeCollection: [], groupsAfterCollection: [], token, mode: alias.targetMode, }; } export type RawTokenData = { token: string; groups: Array; groupList: Array; path: Array; collection: undefined | string; groupsBeforeCollection: Array; groupsAfterCollection: Array; mode: undefined | string; }; export type TokenData = { token: string; groups: string | undefined; groupList: Array; path: string | undefined; collection: undefined | string; groupsBeforeCollectionList: Array; groupsAfterCollectionList: Array; groupsBeforeCollection: string; groupsAfterCollection: string; mode: undefined | string; }; export type TemplateRenderer = (data: RawTokenData) => string; export function renderTemplate(template: string, data: TokenData) { const render = handlebars.compile(template); return render(data); } export function sanitizeData( data: RawTokenData, invalidChars: RegExp, replacer: string, ): TokenData { const groupList = data.groupList.map(group => group.replaceAll(invalidChars, replacer)); const groups = data.groups.length > 0 ? data.groups.join(replacer).replaceAll(invalidChars, replacer) : undefined; const groupsBeforeCollectionList = data.groupsBeforeCollection.map(group => group.replaceAll(invalidChars, replacer), ); const groupsAfterCollectionList = data.groupsAfterCollection.map(group => group.replaceAll(invalidChars, replacer), ); return { token: data.token.replaceAll(invalidChars, replacer), groups, groupList, path: groups, collection: data.collection?.replaceAll(invalidChars, replacer), groupsBeforeCollectionList, groupsAfterCollectionList, groupsBeforeCollection: groupsBeforeCollectionList.join(replacer), groupsAfterCollection: groupsAfterCollectionList.join(replacer), mode: data.mode?.replaceAll(invalidChars, replacer), }; }