@terrazzo/parser
Version:
Parser/validator for the Design Tokens Community Group (DTCG) standard.
52 lines • 2.06 kB
JavaScript
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