@atlaskit/eslint-plugin-design-system
Version:
The essential plugin for use with the Atlassian Design System.
106 lines (99 loc) • 4.04 kB
JavaScript
import { node as generate, isNodeOfType } from 'eslint-codemod-utils';
import { getSourceCode } from '@atlaskit/eslint-utils/context-compat';
import { getIsException } from '../utils/get-is-exception';
import { includesHardCodedColor } from '../utils/includes-hard-coded-color';
import { isHardCodedColor } from '../utils/is-hard-coded-color';
import { isLegacyColor } from '../utils/is-legacy-color';
import { isLegacyNamedColor } from '../utils/is-legacy-named-color';
import { getTokenSuggestion } from './get-token-suggestion';
var TYPESCRIPT_EXPRESSION_WRAPPER_TYPES = new Set(['TSAsExpression', 'TSTypeAssertion', 'TSNonNullExpression', 'TSSatisfiesExpression']);
/**
* TypeScript's expression wrappers are transparent for color classification.
* In particular, `key as readonly string[]` is still the same computed key as
* `key`. Unwrapping before inspecting the member property also keeps the
* codemod stringifier away from type-only nodes it does not support.
*/
var unwrapTypeScriptExpression = function unwrapTypeScriptExpression(node) {
var expression = node;
while (TYPESCRIPT_EXPRESSION_WRAPPER_TYPES.has(expression.type)) {
expression = expression.expression;
}
return expression;
};
// ObjectExpression
export var lintObjectForColor = function lintObjectForColor(propertyNode, context, config) {
var _identifierNode;
var propertyKey = '';
if (propertyNode.key.type === 'Identifier') {
propertyKey = propertyNode.key.name.toString();
}
var node = propertyNode.value;
// ObjectExpression > Property > Literal
if (node.type === 'Literal') {
var _node$value;
var nodeVal = ((_node$value = node.value) === null || _node$value === void 0 ? void 0 : _node$value.toString()) || '';
var _isException = getIsException(config.exceptions);
if ((isHardCodedColor(nodeVal) || includesHardCodedColor(nodeVal)) && !_isException(node)) {
context.report({
messageId: 'hardCodedColor',
node: node,
suggest: getTokenSuggestion(node, "'".concat(nodeVal, "'"), config)
});
}
return;
}
var isException = getIsException(config.exceptions);
// ObjectExpression > Property > CallExpression
if (node.type === 'CallExpression') {
if (!isNodeOfType(node.callee, 'Identifier')) {
return;
}
if (!isLegacyNamedColor(node.callee.name) || isException(node)) {
return;
}
context.report({
messageId: 'hardCodedColor',
node: node,
suggest: getTokenSuggestion(node, "".concat(node.callee.name, "()"), config)
});
return;
}
// Template literals are already handled by 'TemplateLiteral > Identifier' in the main file
if (node.type === 'TemplateLiteral') {
return;
}
var identifierNode = null;
// ObjectExpression > Property > MemberExpression
if (node.type === 'MemberExpression') {
var property = unwrapTypeScriptExpression(node.property);
if (property.type !== 'Identifier') {
context.report({
messageId: 'hardCodedColor',
node: node,
suggest: getTokenSuggestion(node, property === node.property ? generate(node).toString() : getSourceCode(context).getText(node), config)
});
return;
}
identifierNode = property;
}
if (node.type === 'Identifier') {
// identifier is the key and not the value
if (node.name === propertyKey) {
return;
}
identifierNode = node;
}
// ObjectExpression > Property > MemberExpression > Identifier
// ObjectExpression > Property > Identifier
if (((_identifierNode = identifierNode) === null || _identifierNode === void 0 ? void 0 : _identifierNode.type) === 'Identifier') {
if ((isHardCodedColor(identifierNode.name) || includesHardCodedColor(identifierNode.name) || isLegacyColor(identifierNode.name)) && !isException(identifierNode)) {
context.report({
messageId: 'hardCodedColor',
node: identifierNode,
suggest: getTokenSuggestion(identifierNode, identifierNode.name, config)
});
return;
}
}
return;
};