@atlaskit/eslint-plugin-design-system
Version:
The essential plugin for use with the Atlassian Design System.
201 lines (199 loc) • 9.73 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
import { isNodeOfType, literal } from 'eslint-codemod-utils';
import coreIconLabMetadata from '@atlaskit/icon-lab/metadata';
import coreIconMetadata from '@atlaskit/icon/metadata-core';
import { pathWithCustomMessageId } from '../constants';
/**
* __Deprecation icon handler__
*
* A deprecation icon handler which is responsible for displaying an error for deprecated icons.
* It also includes a fixer to replace the deprecated icon with the new icon if a replacement exists.
*/
export var getDeprecationIconHandler = function getDeprecationIconHandler(context) {
var jsxElements = new Map();
var identifiers = new Map();
var importErrors = {};
var exportErrors = {};
var iconNameToImportSource = new Map();
var getConfigFlag = function getConfigFlag(key, defaultValue) {
if (context.options && context.options.length > 0 && context.options[0] && context.options[0].hasOwnProperty(key)) {
return context.options[0][key] === !defaultValue ? !defaultValue : defaultValue;
}
return defaultValue;
};
var getIconComponentName = function getIconComponentName(name) {
return name.split(/\W/).map(function (part) {
return "".concat(part[0].toUpperCase()).concat(part.slice(1));
}).join('').concat('Icon');
};
var createImportError = function createImportError(_ref) {
var node = _ref.node,
importSource = _ref.importSource,
config = _ref.config;
if (config.message) {
var _node$specifiers$;
var myError = {
node: node,
messageId: pathWithCustomMessageId,
data: {
importSource: importSource,
customMessage: config.message,
unfixable: config.unfixable ? 'true' : 'false'
}
};
importErrors[node.source.value] = myError;
var importIconName = (_node$specifiers$ = node.specifiers[0]) === null || _node$specifiers$ === void 0 || (_node$specifiers$ = _node$specifiers$.local) === null || _node$specifiers$ === void 0 ? void 0 : _node$specifiers$.name;
if (importIconName) {
iconNameToImportSource.set(importIconName, importSource);
}
}
};
var createExportError = function createExportError(_ref2) {
var node = _ref2.node,
importSource = _ref2.importSource,
config = _ref2.config;
if (config.message) {
var myError = {
node: node,
messageId: pathWithCustomMessageId,
data: {
importSource: importSource,
customMessage: config.message
}
};
exportErrors[importSource] = myError;
}
};
var throwErrors = function throwErrors() {
var shouldTurnOffAutoFixer = getConfigFlag('turnOffAutoFixer', false);
for (var _i = 0, _Object$entries = Object.entries(importErrors); _i < _Object$entries.length; _i++) {
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
importSource = _Object$entries$_i[0],
error = _Object$entries$_i[1];
if (importSource.includes('/migration/')) {
var _coreIconMetadata$dep, _error$data;
var _importSource$split$s = importSource.split('/').slice(1),
_importSource$split$s2 = _slicedToArray(_importSource$split$s, 4),
_location = _importSource$split$s2[0],
_ = _importSource$split$s2[1],
_migration = _importSource$split$s2[2],
name = _importSource$split$s2[3];
var _name$split = name.split('--'),
_name$split2 = _slicedToArray(_name$split, 2),
deprecatedIconName = _name$split2[0],
legacyIconName = _name$split2[1];
var replacement = (_coreIconMetadata$dep = coreIconMetadata[deprecatedIconName]) === null || _coreIconMetadata$dep === void 0 ? void 0 : _coreIconMetadata$dep.replacement;
if (replacement && ((_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.unfixable) === 'false') {
var newIconName = getIconComponentName(replacement.name);
if (!shouldTurnOffAutoFixer) {
addAutoFix(error, importSource, "".concat(replacement.location, "/core/migration/").concat(replacement.name, "--").concat(legacyIconName), newIconName);
}
}
} else {
var _metadata;
var _importSource$split$s3 = importSource.split('/').slice(1),
_importSource$split$s4 = _slicedToArray(_importSource$split$s3, 3),
location = _importSource$split$s4[0],
_2 = _importSource$split$s4[1],
_name = _importSource$split$s4[2];
var metadata = void 0;
if (location === 'icon') {
metadata = coreIconMetadata;
} else if (location === 'icon-lab') {
metadata = coreIconLabMetadata;
}
var _replacement = (_metadata = metadata) === null || _metadata === void 0 || (_metadata = _metadata[_name]) === null || _metadata === void 0 ? void 0 : _metadata.replacement;
if (_replacement) {
var _newIconName = getIconComponentName(_replacement.name);
if (!shouldTurnOffAutoFixer) {
addAutoFix(error, importSource, "".concat(_replacement.location, "/core/").concat(_replacement.name), _newIconName);
}
}
}
context.report(error);
}
for (var _i2 = 0, _Object$values = Object.values(exportErrors); _i2 < _Object$values.length; _i2++) {
var _error = _Object$values[_i2];
context.report(_error);
}
};
var addAutoFix = function addAutoFix(error, importSource, newImportSource, newIconName) {
error.fix = function (fixer) {
var fixes = [];
//Find and update all usages of this icon in JSX with the replacement icon
var jsxUsageNodes = jsxElements.get(importSource);
if (jsxUsageNodes) {
var _iterator = _createForOfIteratorHelper(jsxUsageNodes),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var usageNode = _step.value;
fixes.push(fixer.replaceText(usageNode.openingElement.name, newIconName));
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
//Find and update all usages of this icon in identifiers with the replacement icon
var usageNodes = identifiers.get(importSource);
if (usageNodes) {
var _iterator2 = _createForOfIteratorHelper(usageNodes),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _usageNode = _step2.value;
fixes.push(fixer.replaceText(_usageNode.parent, "{".concat(newIconName, "}")));
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
}
fixes.push(fixer.replaceText(error.node, "".concat(literal("import ".concat(newIconName, " from '").concat(newImportSource, "'")), ";")));
return fixes;
};
};
var checkJSXElement = function checkJSXElement(node) {
if (!('openingElement' in node) || !isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
return;
}
var iconName = node.openingElement.name.name;
var importSource = iconNameToImportSource.get(iconName);
if (importSource) {
if (jsxElements.has(importSource)) {
var _jsxElements$get;
(_jsxElements$get = jsxElements.get(importSource)) === null || _jsxElements$get === void 0 || _jsxElements$get.push(node);
} else {
jsxElements.set(importSource, [node]);
}
}
};
var checkIdentifier = function checkIdentifier(node) {
if (node.type !== 'Identifier' || node.parent.type !== 'JSXExpressionContainer') {
return;
}
var iconName = node.name;
var importSource = iconNameToImportSource.get(iconName);
if (importSource) {
if (identifiers.has(importSource)) {
var _identifiers$get;
(_identifiers$get = identifiers.get(importSource)) === null || _identifiers$get === void 0 || _identifiers$get.push(node);
} else {
identifiers.set(importSource, [node]);
}
}
};
return {
createImportError: createImportError,
createExportError: createExportError,
checkJSXElement: checkJSXElement,
checkIdentifier: checkIdentifier,
throwErrors: throwErrors
};
};