UNPKG

@terrazzo/parser

Version:

Parser/validator for the Design Tokens Community Group (DTCG) standard.

52 lines 2.06 kB
import { isTokenMatch } from '@terrazzo/token-tools'; import { docsLink } from '../lib/docs.js'; export const REQUIRED_MODES = 'core/required-modes'; const rule = { meta: { docs: { description: 'Enforce certain tokens have specific modes.', url: docsLink(REQUIRED_MODES), }, }, defaultOptions: { matches: [] }, create({ tokens, options, report }) { if (!options?.matches?.length) { throw new Error('Invalid config. Missing `matches: […]`'); } // note: in many other rules, the operation can be completed in one iteration through all tokens // in this rule, however, we have to scan all tokens every time per-match, because they may overlap for (let matchI = 0; matchI < options.matches.length; matchI++) { const { match, modes } = options.matches[matchI]; // validate if (!match.length) { throw new Error(`Match ${matchI}: must declare \`match: […]\``); } if (!modes?.length) { throw new Error(`Match ${matchI}: must declare \`modes: […]\``); } let tokensMatched = false; for (const t of Object.values(tokens)) { if (!isTokenMatch(t.id, match)) { continue; } tokensMatched = true; for (const mode of modes) { if (!t.mode?.[mode]) { report({ message: `Token ${t.id}: missing required mode "${mode}"`, node: t.source.node, }); } } if (!tokensMatched) { report({ message: `Match "${matchI}": no tokens matched ${JSON.stringify(match)}`, node: t.source.node, }); } } } }, }; export default rule; //# sourceMappingURL=required-modes.js.map