@atlaskit/eslint-plugin-design-system 10.18.0 → 10.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 10.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`836af8b0a3b3e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/836af8b0a3b3e) -
8
+ Adds the ability to automigrate more complex automigration cases with multiple of the same icon.
9
+
3
10
  ## 10.18.0
4
11
 
5
12
  ### Minor Changes
package/README.md CHANGED
@@ -68,7 +68,7 @@ module.exports = {
68
68
  | <a href="./src/rules/no-html-button/README.md">no-html-button</a> | Discourage direct usage of HTML button elements in favor of Atlassian Design System button components. | Yes | | |
69
69
  | <a href="./src/rules/no-invalid-css-map/README.md">no-invalid-css-map</a> | Checks the validity of a CSS map created through cssMap. This is intended to be used alongside TypeScript's type-checking. | Yes | | |
70
70
  | <a href="./src/rules/no-keyframes-tagged-template-expression/README.md">no-keyframes-tagged-template-expression</a> | Disallows any `keyframe` tagged template expressions that originate from Emotion, Styled Components or Compiled | | Yes | |
71
- | <a href="./src/rules/no-legacy-icons/README.md">no-legacy-icons</a> | Enforces no legacy icons are used. | | Yes | |
71
+ | <a href="./src/rules/no-legacy-icons/README.md">no-legacy-icons</a> | Enforces no legacy icons are used. | | Yes | Yes |
72
72
  | <a href="./src/rules/no-margin/README.md">no-margin</a> | Disallow using the margin CSS property. | | | |
73
73
  | <a href="./src/rules/no-nested-styles/README.md">no-nested-styles</a> | Disallows use of nested styles in `css` functions. | Yes | | |
74
74
  | <a href="./src/rules/no-physical-properties/README.md">no-physical-properties</a> | Disallow physical properties and values in `css` function calls. | | Yes | |
@@ -1,17 +1,11 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.createChecks = void 0;
8
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
7
  var _eslintCodemodUtils = require("eslint-codemod-utils");
12
8
  var _helpers = require("./helpers");
13
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
9
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
16
10
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
17
11
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
@@ -27,7 +21,6 @@ var createChecks = exports.createChecks = function createChecks(context) {
27
21
  var errorsManual = {};
28
22
  var errorsAuto = {};
29
23
  var guidance = {};
30
- var autoIconJSXElementOccurrenceCount = 0;
31
24
 
32
25
  // Extract parameters
33
26
  var shouldErrorForManualMigration = getConfigFlag('shouldErrorForManualMigration', true);
@@ -58,7 +51,8 @@ var createChecks = exports.createChecks = function createChecks(context) {
58
51
  legacyIconImports[spec.local.name] = {
59
52
  packageName: moduleSource,
60
53
  exported: false,
61
- importNode: node
54
+ importNode: node,
55
+ importSpecifier: spec.local.name
62
56
  };
63
57
  }
64
58
  }
@@ -76,7 +70,8 @@ var createChecks = exports.createChecks = function createChecks(context) {
76
70
  migrationIconImports[spec.local.name] = {
77
71
  packageName: moduleSource,
78
72
  exported: false,
79
- importNode: node
73
+ importNode: node,
74
+ importSpecifier: spec.local.name
80
75
  };
81
76
  }
82
77
  });
@@ -137,7 +132,9 @@ var createChecks = exports.createChecks = function createChecks(context) {
137
132
  if (Object.keys(legacyIconImports).includes(decl.init.name)) {
138
133
  legacyIconImports[decl.id.name] = {
139
134
  packageName: legacyIconImports[decl.init.name].packageName,
140
- exported: legacyIconImports[decl.init.name].exported || isExported
135
+ exported: legacyIconImports[decl.init.name].exported || isExported,
136
+ importNode: legacyIconImports[decl.init.name].importNode,
137
+ importSpecifier: legacyIconImports[decl.init.name].importSpecifier
141
138
  };
142
139
  } else if (newButtonImports.has(decl.init.name)) {
143
140
  newButtonImports.add(decl.id.name);
@@ -181,7 +178,7 @@ var createChecks = exports.createChecks = function createChecks(context) {
181
178
  * @param node The named export node found by ESLint
182
179
  */
183
180
  var checkExportNamedVariables = function checkExportNamedVariables(node) {
184
- // export {default as AddIcon} from '@atlaskit/icon/glyph/add';
181
+ // Case: export {default as AddIcon} from '@atlaskit/icon/glyph/add';
185
182
  if (node.source && (0, _eslintCodemodUtils.isNodeOfType)(node.source, 'Literal') && Object.keys(node.source).includes('value')) {
186
183
  var moduleSource = node.source.value;
187
184
  if (typeof moduleSource === 'string' && ['@atlaskit/icon/glyph/', '@atlaskit/icon-object/glyph/'].find(function (val) {
@@ -206,7 +203,7 @@ var createChecks = exports.createChecks = function createChecks(context) {
206
203
  }
207
204
  }
208
205
  } else if (node.declaration && (0, _eslintCodemodUtils.isNodeOfType)(node.declaration, 'VariableDeclaration')) {
209
- // export const Icon = AddIcon;
206
+ // Case: export const Icon = AddIcon;
210
207
  var _iterator6 = _createForOfIteratorHelper(node.declaration.declarations),
211
208
  _step6;
212
209
  try {
@@ -242,7 +239,9 @@ var createChecks = exports.createChecks = function createChecks(context) {
242
239
  //update legacy imports to be exported
243
240
  legacyIconImports[_spec3.local.name] = {
244
241
  packageName: legacyIconImports[_spec3.local.name].packageName,
245
- exported: true
242
+ exported: true,
243
+ importNode: legacyIconImports[_spec3.local.name].importNode,
244
+ importSpecifier: legacyIconImports[_spec3.local.name].importSpecifier
246
245
  };
247
246
  (0, _helpers.createCantMigrateReExportError)(_spec3, legacyIconImports[_spec3.local.name].packageName, _spec3.exported.name, errorsManual);
248
247
  (0, _helpers.addToListOfRanges)(_spec3, errorRanges);
@@ -497,7 +496,6 @@ var createChecks = exports.createChecks = function createChecks(context) {
497
496
  });
498
497
  var _shouldAddSpaciousSpacing = (_sizeProp && _sizeProp.type === 'JSXAttribute' && ((_sizeProp$value2 = _sizeProp.value) === null || _sizeProp$value2 === void 0 ? void 0 : _sizeProp$value2.type) === 'Literal' && _sizeProp.value.value === 'medium' || !_sizeProp) && !_insideNewButton && !insideLegacyButton;
499
498
  if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
500
- autoIconJSXElementOccurrenceCount++;
501
499
  (0, _helpers.createAutoMigrationError)({
502
500
  node: node,
503
501
  importSource: legacyIconImports[name].packageName,
@@ -551,132 +549,26 @@ var createChecks = exports.createChecks = function createChecks(context) {
551
549
  * Throws the relevant errors in the correct order based on configs.
552
550
  */
553
551
  var throwErrors = function throwErrors() {
552
+ // Throw manual errors
554
553
  if (shouldErrorForManualMigration) {
555
- for (var _i = 0, _Object$entries = Object.entries(errorsManual); _i < _Object$entries.length; _i++) {
556
- var _Object$entries$_i = (0, _slicedToArray2.default)(_Object$entries[_i], 2),
557
- _key = _Object$entries$_i[0],
558
- errorList = _Object$entries$_i[1];
559
- var _node = 'node' in errorList.errors[0] ? errorList.errors[0].node : null;
560
- var cantMigrateIdentifierError = errorList.errors.find(function (x) {
561
- return 'messageId' in x && x.messageId === 'cantMigrateIdentifier';
562
- });
563
- if (_node) {
564
- var isInRange = false;
565
- if (cantMigrateIdentifierError && (0, _helpers.isInRangeList)(_node, errorRanges)) {
566
- isInRange = true;
567
- }
568
- if (isInRange && errorList.errors.length - 1 > 0 || !isInRange && errorList.errors.length > 0) {
569
- var guidanceMessage = Object.keys(guidance).includes(_key) ? guidance[_key] : '';
570
- context.report({
571
- node: _node,
572
- messageId: 'noLegacyIconsManualMigration',
573
- data: {
574
- iconName: errorList.iconName,
575
- importSource: errorList.importSource,
576
- guidance: isQuietMode ? guidanceMessage : "".concat(guidanceMessage, "For more information see the below errors.\n")
577
- }
578
- });
579
- if (!isQuietMode) {
580
- var _iterator10 = _createForOfIteratorHelper(errorList.errors),
581
- _step10;
582
- try {
583
- for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
584
- var error = _step10.value;
585
- if ('messageId' in error && (error.messageId !== 'cantMigrateIdentifier' || error.messageId === 'cantMigrateIdentifier' && !isInRange)) {
586
- context.report(error);
587
- }
588
- }
589
- } catch (err) {
590
- _iterator10.e(err);
591
- } finally {
592
- _iterator10.f();
593
- }
594
- }
595
- }
596
- }
597
- }
554
+ (0, _helpers.throwManualErrors)({
555
+ errorsManual: errorsManual,
556
+ errorRanges: errorRanges,
557
+ guidance: guidance,
558
+ context: context,
559
+ isQuietMode: isQuietMode
560
+ });
598
561
  }
599
562
  if (shouldErrorForAutoMigration) {
600
- var _loop = function _loop() {
601
- var _Object$entries2$_i = (0, _slicedToArray2.default)(_Object$entries2[_i2], 2),
602
- key = _Object$entries2$_i[0],
603
- error = _Object$entries2$_i[1];
604
- // If there's a manual error that exists for this same component,
605
- // don't throw the auto error
606
- if (Object.keys(errorsManual).includes(key)) {
607
- var _cantMigrateIdentifierError = errorsManual[key].errors.find(function (x) {
608
- return 'messageId' in x && x.messageId === 'cantMigrateIdentifier';
609
- });
610
- if (!_cantMigrateIdentifierError || _cantMigrateIdentifierError && errorsManual[key].errors.length > 1) {
611
- delete errorsAuto[key];
612
- return 1; // continue
613
- }
614
- }
615
- var node = 'node' in error ? error.node : null;
616
- if (node) {
617
- var _guidanceMessage = Object.keys(guidance).includes(key) ? guidance[key] : '';
618
- if (Object.keys(error).includes('data') && error.data) {
619
- error.data.guidance = _guidanceMessage;
620
- }
621
- context.report(_objectSpread(_objectSpread({}, error), {}, {
622
- fix: function fix(fixer) {
623
- var _legacyIconImports$er, _migrationIconImports;
624
- // don't migration if the new icon is not available
625
- if (!error.data || shouldUseMigrationPath && !(0, _helpers.checkIfNewIconExist)(error)) {
626
- return [];
627
- }
628
- var fixArguments = {
629
- metadata: error.data,
630
- legacyImportNode: (_legacyIconImports$er = legacyIconImports[error.data.iconName]) === null || _legacyIconImports$er === void 0 ? void 0 : _legacyIconImports$er.importNode,
631
- migrationImportNode: (_migrationIconImports = migrationIconImports[error.data.iconName]) === null || _migrationIconImports === void 0 ? void 0 : _migrationIconImports.importNode,
632
- shouldUseMigrationPath: shouldUseMigrationPath
633
- };
634
- var propsFixes = (0, _helpers.createPropFixes)(_objectSpread(_objectSpread({}, fixArguments), {}, {
635
- node: node,
636
- fixer: fixer
637
- }));
638
- var importFixes = [];
639
- // Otherwise if there are multiple occurrences of the icon, import path will be handled after the prop fix
640
- if (autoIconJSXElementOccurrenceCount <= 1) {
641
- importFixes = (0, _helpers.createImportFix)(_objectSpread(_objectSpread({}, fixArguments), {}, {
642
- fixer: fixer
643
- }));
644
- }
645
- return [].concat((0, _toConsumableArray2.default)(propsFixes), (0, _toConsumableArray2.default)(importFixes));
646
- }
647
- }));
648
- }
649
- };
650
- for (var _i2 = 0, _Object$entries2 = Object.entries(errorsAuto); _i2 < _Object$entries2.length; _i2++) {
651
- if (_loop()) continue;
652
- }
653
-
654
- // Update import path at the end if there are multiple occurrences of the icon
655
- if (autoIconJSXElementOccurrenceCount > 1) {
656
- var _loop2 = function _loop2() {
657
- var _Object$entries3$_i = (0, _slicedToArray2.default)(_Object$entries3[_i3], 2),
658
- _ = _Object$entries3$_i[0],
659
- error = _Object$entries3$_i[1];
660
- context.report(_objectSpread(_objectSpread({}, error), {}, {
661
- fix: function fix(fixer) {
662
- var _legacyIconImports$er2, _migrationIconImports2;
663
- if (!error.data || shouldUseMigrationPath && !(0, _helpers.checkIfNewIconExist)(error)) {
664
- return [];
665
- }
666
- return (0, _helpers.createImportFix)({
667
- metadata: error.data,
668
- fixer: fixer,
669
- legacyImportNode: (_legacyIconImports$er2 = legacyIconImports[error.data.iconName]) === null || _legacyIconImports$er2 === void 0 ? void 0 : _legacyIconImports$er2.importNode,
670
- migrationImportNode: (_migrationIconImports2 = migrationIconImports[error.data.iconName]) === null || _migrationIconImports2 === void 0 ? void 0 : _migrationIconImports2.importNode,
671
- shouldUseMigrationPath: shouldUseMigrationPath
672
- });
673
- }
674
- }));
675
- };
676
- for (var _i3 = 0, _Object$entries3 = Object.entries(errorsAuto); _i3 < _Object$entries3.length; _i3++) {
677
- _loop2();
678
- }
679
- }
563
+ (0, _helpers.throwAutoErrors)({
564
+ errorsManual: errorsManual,
565
+ errorsAuto: errorsAuto,
566
+ legacyIconImports: legacyIconImports,
567
+ guidance: guidance,
568
+ migrationIconImports: migrationIconImports,
569
+ shouldUseMigrationPath: shouldUseMigrationPath,
570
+ context: context
571
+ });
680
572
  }
681
573
  };
682
574
  return {
@@ -5,13 +5,20 @@ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.locToString = exports.isSize = exports.isInsideNewButton = exports.isInsideLegacyButton = exports.isInRangeList = exports.getUpcomingIcons = exports.getNewIconNameAndImportPath = exports.getMigrationMapObject = exports.getLiteralStringValue = exports.createPropFixes = exports.createImportFix = exports.createHelpers = exports.createGuidance = exports.createCantMigrateSpreadPropsError = exports.createCantMigrateSizeUnknown = exports.createCantMigrateReExportError = exports.createCantMigrateIdentifierMapOrArrayError = exports.createCantMigrateIdentifierError = exports.createCantMigrateFunctionUnknownError = exports.createCantMigrateColorError = exports.createCantFindSuitableReplacementError = exports.createAutoMigrationError = exports.checkIfNewIconExist = exports.canMigrateColor = exports.canAutoMigrateNewIconBasedOnSize = exports.addToListOfRanges = void 0;
8
+ exports.throwManualErrors = exports.throwAutoErrors = exports.locToString = exports.isSize = exports.isInsideNewButton = exports.isInsideLegacyButton = exports.getUpcomingIcons = exports.getMigrationMapObject = exports.createHelpers = exports.createGuidance = exports.createCantMigrateSpreadPropsError = exports.createCantMigrateSizeUnknown = exports.createCantMigrateReExportError = exports.createCantMigrateIdentifierMapOrArrayError = exports.createCantMigrateIdentifierError = exports.createCantMigrateFunctionUnknownError = exports.createCantMigrateColorError = exports.createCantFindSuitableReplacementError = exports.createAutoMigrationError = exports.canMigrateColor = exports.canAutoMigrateNewIconBasedOnSize = exports.addToListOfRanges = void 0;
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
11
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
12
  var _eslintCodemodUtils = require("eslint-codemod-utils");
11
13
  var _UNSAFE_migrationMap = _interopRequireWildcard(require("@atlaskit/icon/UNSAFE_migration-map"));
12
14
  var _upcomingIcons = require("./upcoming-icons");
13
15
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
14
16
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
20
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
21
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
15
22
  var sizes = ['small', 'medium', 'large', 'xlarge'];
16
23
  var isSize = exports.isSize = function isSize(size) {
17
24
  return sizes.includes(size);
@@ -67,7 +74,7 @@ var canAutoMigrateNewIconBasedOnSize = exports.canAutoMigrateNewIconBasedOnSize
67
74
  * @param iconPackage string
68
75
  * @returns object of new icon name and import path
69
76
  */
70
- var getNewIconNameAndImportPath = exports.getNewIconNameAndImportPath = function getNewIconNameAndImportPath(iconPackage, shouldUseMigrationPath) {
77
+ var getNewIconNameAndImportPath = function getNewIconNameAndImportPath(iconPackage, shouldUseMigrationPath) {
71
78
  var legacyIconName = getIconKey(iconPackage);
72
79
  var migrationMapObject = getMigrationMapObject(iconPackage);
73
80
  if (!migrationMapObject || !migrationMapObject.newIcon) {
@@ -298,7 +305,7 @@ var pushManualError = function pushManualError(key, errors, myError, importSourc
298
305
  };
299
306
  }
300
307
  };
301
- var getLiteralStringValue = exports.getLiteralStringValue = function getLiteralStringValue(value) {
308
+ var getLiteralStringValue = function getLiteralStringValue(value) {
302
309
  if (!value) {
303
310
  return;
304
311
  }
@@ -366,7 +373,7 @@ var addToListOfRanges = exports.addToListOfRanges = function addToListOfRanges(n
366
373
  });
367
374
  }
368
375
  };
369
- var isInRangeList = exports.isInRangeList = function isInRangeList(node, sortedListOfRangesForErrors) {
376
+ var isInRangeList = function isInRangeList(node, sortedListOfRangesForErrors) {
370
377
  var range = node.range;
371
378
  if (!range || range.length < 2) {
372
379
  return false;
@@ -411,6 +418,18 @@ var findProp = function findProp(attributes, propName) {
411
418
  return attr.type === 'JSXAttribute' && attr.name.name === propName;
412
419
  });
413
420
  };
421
+ var getNewIconNameForRenaming = function getNewIconNameForRenaming(isInManualArray, importSource, importSpecifier) {
422
+ var newIconName;
423
+ if (isInManualArray) {
424
+ newIconName = getNewIconNameAndImportPath(importSource).iconName;
425
+ var keyToName = newIconName ? newIconName[0].toUpperCase() + newIconName.slice(1) + 'Icon' : undefined;
426
+ newIconName = keyToName;
427
+ if (newIconName === undefined || importSpecifier === keyToName) {
428
+ newIconName = "".concat(keyToName, "New");
429
+ }
430
+ }
431
+ return newIconName;
432
+ };
414
433
 
415
434
  /**
416
435
  *
@@ -422,22 +441,22 @@ var findProp = function findProp(attributes, propName) {
422
441
  * @param migrationImportNode The migration import declaration node to replace, only present if shouldUseMigrationPath is false
423
442
  * @returns A list of fixers to migrate the icon
424
443
  */
425
- var createImportFix = exports.createImportFix = function createImportFix(_ref6) {
444
+ var createImportFix = function createImportFix(_ref6) {
426
445
  var fixer = _ref6.fixer,
427
446
  legacyImportNode = _ref6.legacyImportNode,
428
447
  metadata = _ref6.metadata,
429
448
  shouldUseMigrationPath = _ref6.shouldUseMigrationPath,
430
- migrationImportNode = _ref6.migrationImportNode;
449
+ migrationImportNode = _ref6.migrationImportNode,
450
+ newIconName = _ref6.newIconName;
431
451
  var fixes = [];
432
452
  var importSource = metadata.importSource;
433
453
  var importPath = migrationImportNode ? importSource.replace('/migration', '').split('--')[0] : getNewIconNameAndImportPath(importSource, shouldUseMigrationPath).importPath;
434
-
435
- // replace old icon import with icon import
436
- if (legacyImportNode && importPath) {
437
- fixes.push(fixer.replaceText(legacyImportNode.source, "'".concat((0, _eslintCodemodUtils.literal)(importPath), "'")));
438
- }
439
- if (migrationImportNode && !shouldUseMigrationPath && importPath) {
440
- fixes.push(fixer.replaceText(migrationImportNode.source, "'".concat((0, _eslintCodemodUtils.literal)(importPath), "'")));
454
+ var useMigrationPath = legacyImportNode && importPath;
455
+ var useFinalPath = migrationImportNode && !shouldUseMigrationPath && importPath;
456
+ if (useMigrationPath) {
457
+ fixes.push(newIconName ? fixer.insertTextBefore(legacyImportNode, "import ".concat(newIconName, " from '").concat(importPath, "';\n")) : fixer.replaceText(legacyImportNode.source, "'".concat((0, _eslintCodemodUtils.literal)(importPath), "'")));
458
+ } else if (useFinalPath) {
459
+ fixes.push(newIconName ? fixer.insertTextBefore(migrationImportNode, "import ".concat(newIconName, " from '").concat(importPath, "';\n")) : fixer.replaceText(migrationImportNode.source, "'".concat((0, _eslintCodemodUtils.literal)(importPath), "'")));
441
460
  }
442
461
  return fixes;
443
462
  };
@@ -452,13 +471,14 @@ var createImportFix = exports.createImportFix = function createImportFix(_ref6)
452
471
  * @param migrationImportNode The migration import declaration node to replace, only present if shouldUseMigrationPath is false
453
472
  * @returns A list of fixers to migrate the icon
454
473
  */
455
- var createPropFixes = exports.createPropFixes = function createPropFixes(_ref7) {
474
+ var createPropFixes = function createPropFixes(_ref7) {
456
475
  var node = _ref7.node,
457
476
  fixer = _ref7.fixer,
458
477
  legacyImportNode = _ref7.legacyImportNode,
459
478
  metadata = _ref7.metadata,
460
479
  shouldUseMigrationPath = _ref7.shouldUseMigrationPath,
461
- migrationImportNode = _ref7.migrationImportNode;
480
+ migrationImportNode = _ref7.migrationImportNode,
481
+ newIconName = _ref7.newIconName;
462
482
  var fixes = [];
463
483
  var importSource = metadata.importSource,
464
484
  spacing = metadata.spacing,
@@ -470,6 +490,9 @@ var createPropFixes = exports.createPropFixes = function createPropFixes(_ref7)
470
490
  var iconType = importPath !== null && importPath !== void 0 && importPath.startsWith('@atlaskit/icon/core') ? 'core' : 'utility';
471
491
  if (node.type === 'JSXElement') {
472
492
  var openingElement = node.openingElement;
493
+ if (newIconName) {
494
+ fixes.push(fixer.replaceText(openingElement.name, newIconName));
495
+ }
473
496
  var attributes = openingElement.attributes;
474
497
 
475
498
  // replace primaryColor prop with color
@@ -526,6 +549,8 @@ var createPropFixes = exports.createPropFixes = function createPropFixes(_ref7)
526
549
  }
527
550
  });
528
551
  }
552
+ } else if (node.type === 'Identifier' && newIconName) {
553
+ fixes.push(fixer.replaceText(node, newIconName));
529
554
  }
530
555
  return fixes;
531
556
  };
@@ -533,7 +558,7 @@ var createPropFixes = exports.createPropFixes = function createPropFixes(_ref7)
533
558
  /**
534
559
  * Check if the new icon exists in the migration map
535
560
  */
536
- var checkIfNewIconExist = exports.checkIfNewIconExist = function checkIfNewIconExist(error) {
561
+ var checkIfNewIconExist = function checkIfNewIconExist(error) {
537
562
  var _error$data;
538
563
  if (!((_error$data = error.data) !== null && _error$data !== void 0 && _error$data.importSource)) {
539
564
  return false;
@@ -542,4 +567,210 @@ var checkIfNewIconExist = exports.checkIfNewIconExist = function checkIfNewIconE
542
567
  var _ref8 = _UNSAFE_migrationMap.default[iconKey] || {},
543
568
  newIcon = _ref8.newIcon;
544
569
  return Boolean(newIcon);
570
+ };
571
+ var throwManualErrors = exports.throwManualErrors = function throwManualErrors(_ref9) {
572
+ var errorsManual = _ref9.errorsManual,
573
+ errorRanges = _ref9.errorRanges,
574
+ guidance = _ref9.guidance,
575
+ context = _ref9.context,
576
+ isQuietMode = _ref9.isQuietMode;
577
+ for (var _i2 = 0, _Object$entries2 = Object.entries(errorsManual); _i2 < _Object$entries2.length; _i2++) {
578
+ var _Object$entries2$_i = (0, _slicedToArray2.default)(_Object$entries2[_i2], 2),
579
+ _key = _Object$entries2$_i[0],
580
+ errorList = _Object$entries2$_i[1];
581
+ var node = 'node' in errorList.errors[0] ? errorList.errors[0].node : null;
582
+ if (!node) {
583
+ return;
584
+ }
585
+ var cantMigrateIdentifierError = errorList.errors.find(function (x) {
586
+ return 'messageId' in x && x.messageId === 'cantMigrateIdentifier';
587
+ });
588
+ var isInRange = false;
589
+ if (cantMigrateIdentifierError && isInRangeList(node, errorRanges)) {
590
+ isInRange = true;
591
+ }
592
+ if (isInRange && errorList.errors.length - 1 > 0 || !isInRange && errorList.errors.length > 0) {
593
+ var guidanceMessage = Object.keys(guidance).includes(_key) ? guidance[_key] : '';
594
+ context.report({
595
+ node: node,
596
+ messageId: 'noLegacyIconsManualMigration',
597
+ data: {
598
+ iconName: errorList.iconName,
599
+ importSource: errorList.importSource,
600
+ guidance: isQuietMode ? guidanceMessage : "".concat(guidanceMessage, "For more information see the below errors.\n")
601
+ }
602
+ });
603
+ if (!isQuietMode) {
604
+ var _iterator = _createForOfIteratorHelper(errorList.errors),
605
+ _step;
606
+ try {
607
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
608
+ var error = _step.value;
609
+ if ('messageId' in error && (error.messageId !== 'cantMigrateIdentifier' || error.messageId === 'cantMigrateIdentifier' && !isInRange)) {
610
+ context.report(error);
611
+ }
612
+ }
613
+ } catch (err) {
614
+ _iterator.e(err);
615
+ } finally {
616
+ _iterator.f();
617
+ }
618
+ }
619
+ }
620
+ }
621
+ };
622
+
623
+ // Loops through automatic errors and them after adding the required suggestion/fix
624
+ var throwAutoErrors = exports.throwAutoErrors = function throwAutoErrors(_ref10) {
625
+ var errorsManual = _ref10.errorsManual,
626
+ errorsAuto = _ref10.errorsAuto,
627
+ legacyIconImports = _ref10.legacyIconImports,
628
+ guidance = _ref10.guidance,
629
+ migrationIconImports = _ref10.migrationIconImports,
630
+ shouldUseMigrationPath = _ref10.shouldUseMigrationPath,
631
+ context = _ref10.context;
632
+ // Set of all the import sources that have manual errors (required later to check if a source has both manual and auto
633
+ // errors in one file making it impossible to just remove the legacy import)
634
+ var allManualErrorSources = Object.entries(errorsManual).reduce(function (result, option) {
635
+ var _option = (0, _slicedToArray2.default)(option, 2),
636
+ key = _option[0],
637
+ errorInfo = _option[1];
638
+ if (!errorsAuto.hasOwnProperty(key)) {
639
+ result.add(errorInfo.importSource);
640
+ }
641
+ return result;
642
+ }, new Set());
643
+ //group errors by import source and remove any unwanted errors
644
+ var groupedErrorList = Object.entries(errorsAuto).reduce(function (result, option) {
645
+ var _option2 = (0, _slicedToArray2.default)(option, 2),
646
+ key = _option2[0],
647
+ error = _option2[1];
648
+ //return early if no data
649
+ if (!error.data) {
650
+ return result;
651
+ }
652
+ if (Object.keys(errorsManual).includes(key)) {
653
+ var cantMigrateIdentifierError = errorsManual[key].errors.find(function (x) {
654
+ return 'messageId' in x && x.messageId === 'cantMigrateIdentifier';
655
+ });
656
+ // If cantMigrateIdentifier is the only manual error found we still want to throw the auto error
657
+ if (!(cantMigrateIdentifierError && errorsManual[key].errors.length === 1)) {
658
+ return result;
659
+ }
660
+ }
661
+ var importSource = error.data.importSource;
662
+ if (!result.hasOwnProperty(importSource)) {
663
+ result[importSource] = [];
664
+ }
665
+ result[importSource].push(_objectSpread({
666
+ key: key
667
+ }, error));
668
+ return result;
669
+ }, {});
670
+ var _loop = function _loop() {
671
+ var _Object$entries3$_i = (0, _slicedToArray2.default)(_Object$entries3[_i3], 2),
672
+ importSource = _Object$entries3$_i[0],
673
+ errorList = _Object$entries3$_i[1];
674
+ var autoFixers = [];
675
+ // appliedErrorsForImport will contain all the errors FOR A SINGLE IMPORT and will be merged into errorListForReport
676
+ var appliedErrorsForImport = [];
677
+ // Loop over auto errors for a single import source
678
+ var _iterator2 = _createForOfIteratorHelper(errorList.entries()),
679
+ _step2;
680
+ try {
681
+ var _loop2 = function _loop2() {
682
+ var _legacyIconImports$er, _legacyIconImports$er2, _migrationIconImports;
683
+ var _step2$value = (0, _slicedToArray2.default)(_step2.value, 2),
684
+ _ = _step2$value[0],
685
+ error = _step2$value[1];
686
+ var key = error.key;
687
+ var node = 'node' in error ? error.node : null;
688
+ // Check if there is a manual error for the same import source somewhere else in the same file
689
+ // If that is the case we'll need to provide a suggestion instead of auto-fixing as the suggestion will
690
+ // add another import without removing the old import and this needs to be validated
691
+ var isInManualArray = allManualErrorSources.has(importSource);
692
+ // New icon name for renaming if the icon is in the manual array
693
+ var newIconName = getNewIconNameForRenaming(isInManualArray, importSource, errorList[0].data ? (_legacyIconImports$er = legacyIconImports[errorList[0].data.iconName]) === null || _legacyIconImports$er === void 0 ? void 0 : _legacyIconImports$er.importSpecifier : undefined);
694
+ if (!node) {
695
+ return 0; // continue
696
+ }
697
+ var guidanceMessage = guidance.hasOwnProperty(key) ? guidance[key] : '';
698
+ if (Object.keys(error).includes('data') && error.data) {
699
+ error.data.guidance = guidanceMessage;
700
+ }
701
+ var fixArguments = error.data ? {
702
+ metadata: error.data,
703
+ legacyImportNode: (_legacyIconImports$er2 = legacyIconImports[error.data.iconName]) === null || _legacyIconImports$er2 === void 0 ? void 0 : _legacyIconImports$er2.importNode,
704
+ migrationImportNode: (_migrationIconImports = migrationIconImports[error.data.iconName]) === null || _migrationIconImports === void 0 ? void 0 : _migrationIconImports.importNode,
705
+ shouldUseMigrationPath: shouldUseMigrationPath,
706
+ newIconName: isInManualArray ? newIconName : undefined
707
+ } : null;
708
+ if (!error.data || shouldUseMigrationPath && !checkIfNewIconExist(error) || !fixArguments) {
709
+ return 0; // continue
710
+ }
711
+ if (isInManualArray) {
712
+ // provide suggestion if there is a manual error for the same import source and thus the legacy import can't be removed
713
+ error.suggest = [{
714
+ desc: 'Rename icon import, import from the new package, and update props.',
715
+ fix: function fix(fixer) {
716
+ return [].concat((0, _toConsumableArray2.default)(createPropFixes(_objectSpread(_objectSpread({}, fixArguments), {}, {
717
+ node: node,
718
+ fixer: fixer
719
+ }))), (0, _toConsumableArray2.default)(createImportFix(_objectSpread(_objectSpread({}, fixArguments), {}, {
720
+ fixer: fixer
721
+ }))));
722
+ }
723
+ }];
724
+ } else {
725
+ // Update Guidance message for auto-fixing
726
+ if (error.data) {
727
+ error.data.guidance = error.data.guidance + "\nTo automatically fix this icon, run the auto-fixer attached to the first use of ".concat(importSource, " in this file - either manually, or by saving this file.");
728
+ }
729
+ // There should only be 1 import fix for each import source and thus only add this at the start of the list
730
+ if (autoFixers.length === 0) {
731
+ autoFixers.push(function (fixer) {
732
+ return createImportFix(_objectSpread(_objectSpread({}, fixArguments), {}, {
733
+ fixer: fixer
734
+ }));
735
+ });
736
+ }
737
+ // Push the prop fix regardless
738
+ autoFixers.push(function (fixer) {
739
+ return createPropFixes(_objectSpread(_objectSpread({}, fixArguments), {}, {
740
+ node: node,
741
+ fixer: fixer
742
+ }));
743
+ });
744
+ }
745
+ // Add the error to the appliedErrorsForImport, ready to be thrown later
746
+ appliedErrorsForImport.push(error);
747
+ },
748
+ _ret;
749
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
750
+ _ret = _loop2();
751
+ if (_ret === 0) continue;
752
+ }
753
+ // We want to have only 1 fix for each import source that is not in the manual array
754
+ // NOTE: If in the manual array, suggestions have been applied above and autoFixers.length will be 0 which will mean no fix is added
755
+ } catch (err) {
756
+ _iterator2.e(err);
757
+ } finally {
758
+ _iterator2.f();
759
+ }
760
+ if (autoFixers.length > 0) {
761
+ // Add the fix to only one of the errors in the list of errors from the current import source
762
+ appliedErrorsForImport[0].fix = function (fixer) {
763
+ return autoFixers.flatMap(function (autoFixer) {
764
+ return autoFixer(fixer);
765
+ });
766
+ };
767
+ }
768
+ // throw errors
769
+ appliedErrorsForImport.forEach(function (error) {
770
+ context.report(error);
771
+ });
772
+ };
773
+ for (var _i3 = 0, _Object$entries3 = Object.entries(groupedErrorList); _i3 < _Object$entries3.length; _i3++) {
774
+ _loop();
775
+ }
545
776
  };
@@ -12,6 +12,7 @@ var rule = (0, _createRule.createLintRule)({
12
12
  meta: {
13
13
  name: 'no-legacy-icons',
14
14
  fixable: 'code',
15
+ hasSuggestions: true,
15
16
  type: 'problem',
16
17
  docs: {
17
18
  description: 'Enforces no legacy icons are used.',