import type { DeriveBuiltInParserHandlerFromDefinition } from '../../internals/createBuiltInParserDefinition.js'; import type { ToTailwindParserDefinition } from './definition.js'; import { createSDTFEngine, SDTFEngine, SpecifyDesignTokenTypeName, } from '@specifyapp/specify-design-token-format'; import { inspect } from 'node:util'; import { filterAuthorizedToken } from '../../utils/filterToken.js'; import { tokensToTailwindPreset } from './tokenToTailwind.js'; import { DEFAULT_TOKEN_NOT_IN_COLLECTION_TEMPLATE, DEFAULT_TOKEN_TEMPLATE, } from '../../shared/to-css-custom-properties/template.js'; import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { FilesOutput } from '../../../parsersEngine/definitions/parserOutput.js'; export const AUTHORIZED_TOKENS: Array = [ 'bitmap', 'blur', 'border', 'breakpoint', 'color', 'cubicBezier', 'dimension', 'duration', 'font', 'fontFamily', 'fontWeight', 'gradient', 'gradients', 'opacity', 'radii', 'radius', 'shadow', 'shadows', 'spacing', 'spacings', 'stepsTimingFunction', 'textStyle', 'transition', 'vector', 'zIndex', ]; export const toTailwindHandler: DeriveBuiltInParserHandlerFromDefinition< ToTailwindParserDefinition > = async (previousDataBox, toolbox, parserOptions, outputOptions, _context) => { let sdtfEngine: SDTFEngine; switch (previousDataBox.type) { case 'SDTF': { sdtfEngine = createSDTFEngine(previousDataBox.graph, previousDataBox.metadata); break; } case 'SDTF Engine': { sdtfEngine = previousDataBox.engine; break; } default: { throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_PARSER_INPUT.errorKey, publicMessage: `${ (previousDataBox as any).type } is not a valid input for the to-tailwind parser.`, }); } } if (outputOptions?.type !== 'file') throw new SpecifyError({ errorKey: specifyErrors.PARSERS_ENGINE_INVALID_OUTPUT_TYPE.errorKey, publicMessage: `The output type ${outputOptions?.type} is not supported by the to-tailwind parser.`, }); const tokenStates = sdtfEngine.query .getAllTokenStates() .filter(filterAuthorizedToken(AUTHORIZED_TOKENS)); let output: FilesOutput['files'] = []; if (tokenStates.length === 0) { toolbox.populateMessage({ type: 'warning', content: `No design tokens found in the input`, errorKey: specifyErrors.PARSERS_ENGINE_PARSER_EXECUTION_FAILED.errorKey, }); output = []; } else { const tailwindPreset = tokensToTailwindPreset( tokenStates, { useCssVariable: parserOptions?.useCssVariable ?? false, cssVariableTemplate: { tokenNameTemplate: parserOptions?.cssVariableTemplate?.tokenNameTemplate ?? DEFAULT_TOKEN_TEMPLATE, tokenNotInCollectionNameTemplate: parserOptions?.cssVariableTemplate?.tokenNotInCollectionNameTemplate ?? DEFAULT_TOKEN_NOT_IN_COLLECTION_TEMPLATE, }, removeSingleMode: parserOptions?.removeSingleMode ?? true, removeModesIfSameValue: parserOptions?.removeModesIfSameValue ?? true, }, toolbox, ); output = [ { path: outputOptions.filePath, content: { type: 'text', text: `/** @type {import('tailwindcss').Config} */\nmodule.exports = ${inspect( tailwindPreset, { depth: 64 }, )}`, }, }, ]; } toolbox.populateOutput({ type: 'files', files: output, }); return { type: 'SDTF Engine', engine: sdtfEngine, }; };