UNPKG

@terrazzo/parser

Version:

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

106 lines 4.09 kB
import { getObjMember } from '@terrazzo/json-schema-tools'; import { isAlias } from '@terrazzo/token-tools'; import { docsLink } from '../lib/docs.js'; export const VALID_DURATION = 'core/valid-duration'; const ERROR_FORMAT = 'ERROR_FORMAT'; const ERROR_INVALID_PROP = 'ERROR_INVALID_PROP'; const ERROR_LEGACY = 'ERROR_LEGACY'; const ERROR_UNIT = 'ERROR_UNIT'; const ERROR_VALUE = 'ERROR_VALUE'; const rule = { meta: { messages: { [ERROR_FORMAT]: 'Migrate to the new object format: { "value": 2, "unit": "ms" }.', [ERROR_LEGACY]: 'Migrate to the new object format: { "value": 10, "unit": "px" }.', [ERROR_INVALID_PROP]: 'Unknown property: {{ key }}.', [ERROR_UNIT]: 'Unknown unit {{ unit }}. Expected "ms" or "s".', [ERROR_VALUE]: 'Expected number, received {{ value }}.', }, docs: { description: 'Require duration tokens to follow the format', url: docsLink(VALID_DURATION), }, }, defaultOptions: { legacyFormat: false, unknownUnits: false, }, create({ tokens, options, report }) { for (const t of Object.values(tokens)) { if (t.aliasOf || !t.originalValue) { continue; } switch (t.$type) { case 'duration': { validateDuration(t.originalValue.$value, { node: getObjMember(t.source.node, '$value'), filename: t.source.filename, options, report, }); break; } case 'transition': { if (typeof t.originalValue.$value === 'object') { const $valueNode = getObjMember(t.source.node, '$value'); for (const property of ['duration', 'delay']) { if (t.originalValue.$value[property] && !isAlias(t.originalValue.$value[property])) { validateDuration(t.originalValue.$value[property], { node: getObjMember($valueNode, property), filename: t.source.filename, options, report, }); } } } break; } } } }, }; function validateDuration(value, { node, filename, options, report, }) { if (value && typeof value === 'object') { for (const key of Object.keys(value)) { if (!['value', 'unit'].includes(key)) { report({ data: { key: JSON.stringify(key) }, filename, messageId: ERROR_INVALID_PROP, node: getObjMember(node, key) ?? node, }); } } const { unit, value: numValue } = value; if (!('value' in value || 'unit' in value)) { report({ data: { value }, filename, messageId: ERROR_FORMAT, node }); return; } if (!options.unknownUnits && !['ms', 's'].includes(unit)) { report({ data: { unit }, filename, messageId: ERROR_UNIT, node: getObjMember(node, 'unit') ?? node, }); } if (!Number.isFinite(numValue)) { report({ data: { value }, filename, messageId: ERROR_VALUE, node: getObjMember(node, 'value') ?? node, }); } } else if (typeof value === 'string' && !options.legacyFormat) { report({ filename, messageId: ERROR_FORMAT, node }); } else { report({ data: { value }, filename, messageId: ERROR_FORMAT, node }); } } export default rule; //# sourceMappingURL=valid-duration.js.map